Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mac OSX get USB vendor id and product id

Tags:

bash

macos

usb

I'm a newbie in Mac OSX world and I have to write a script which gives me the vendor id and product id of a connected usb device. I have done it for Windows and Linux but for Mac I have no idea where to start from.

I have seen this post but the link with the example is not working. Do you guys have any advice about where I can start from or where I can find some examples?

In particular, which language should I use?

like image 532
Sceik Avatar asked Feb 26 '14 13:02

Sceik


1 Answers

You tagged your question with bash, so I'll answer it as if you're asking how to do this in bash, rather than asking what language to use (which would make the question off-topic for StackOverflow).

You can parse existing data from system_profiler using built-in tools. For example, here's a dump of vendor:product pairs, with "Location ID" and manufacturer...

#!/bin/bash

shopt -s extglob

while IFS=: read key value; do
  key="${key##+( )}"
  value="${value##+( )}"
  case "$key" in
    "Product ID")
        p="${value% *}"
        ;;
    "Vendor ID")
        v="${value%% *}"
        ;;
    "Manufacturer")
        m="${value}"
        ;;
    "Location ID")
        l="${value}"
        printf "%s:%s %s (%s)\n" "$v" "$p" "$l" "$m"
        ;;
  esac
done < <( system_profiler SPUSBDataType )

This relies on the fact that Location ID is the last item listed for each USB device, which I haven't verified conclusively. (It just appears that way for me.)

If you want something that (1) is easier to read and (2) doesn't depend on bash and is therefore more portable (not an issue though; all Macs come with bash), you might want to consider doing your heavy lifting in awk instead of pure bash:

#!/bin/sh

system_profiler SPUSBDataType \
    | awk '
      /Product ID:/{p=$3}
      /Vendor ID:/{v=$3}
      /Manufacturer:/{sub(/.*: /,""); m=$0}
      /Location ID:/{sub(/.*: /,""); printf("%s:%s %s (%s)\n", v, p, $0, m);}
    '

Or even avoid wrapping this in shell entirely with:

#!/usr/bin/awk -f

BEGIN {

  while ("system_profiler SPUSBDataType" | getline) {
    if (/Product ID:/)   {p=$3}
    if (/Vendor ID:/)    {v=$3}
    if (/Manufacturer:/) {sub(/.*: /,""); m=$0}
    if (/Location ID:/)  {sub(/.*: /,""); printf("%s:%s %s (%s)\n", v, p, $0, m)}
  }

}

Note that you can also get output from system_profiler in XML format:

$ system_profiler -xml SPUSBDataType

You'll need an XML parser to handle that output, though. And you'll find that it's a lot of work to parse XML in native bash.

like image 117
ghoti Avatar answered Oct 17 '22 09:10

ghoti