How to get Bus and Device relationship for a /dev/ttyUSB
Since I don't have your hardware I can't give you an exact answer.
I'd suggest that you go to the device in question, for example:
ls -l /dev/ttyUSB0
and obtain the major and minor node numbers. Let's say they are 116, 7
Then go to:
ls -l /sys/dev/char/116:7
(char
, because a tty is a character device, if you were tracing down a disk device you would specify block
instead of char
)
In the output from the command you will see something a little like:
lrwxrwxrwx 1 root root 0 Sep 6 00:17 116:7 -> ../../devices//sys/devices/pci0000:00/0000:00:13.5/pci0000:00/0000:00:13.5/usb1/1-3/1-3:1.1/sound/card1/pcmC1D0c
The directory /sys/devices/pci0000:00/0000:00:13.5/usb1/1-3/
and its subdirectories have much information on the device. As an example, /sys/devices/pci0000:00/0000:00:13.5/usb1/1-3/busnum
and /sys/devices/pci0000:00/0000:00:13.5/usb1/1-3/devnum
. On my system these match the bus and device number mentioned in the device hotplug entries in /var/log/syslog.
Something else that works on my system for /dev/video0:
find /sys/dev -lname '*video0' -exec cat {}/device/busnum {}/device/devnum \; 2>/dev/null
There really isn't a good way to map character devices like /dev/ttyUSB0
to the corresponding USB device and bus numbers. BUT, it is possible!
Something like this might work:
udevadm info --name=/dev/ttyUSB0 --attribute-walk
From there, you'll get a bunch of information about the device and its parent devices. Now, it's just all about parsing those data to get what you want. I've used this in the past:
echo /dev/bus/usb/`udevadm info --name=/dev/ttyUSB0 --attribute-walk | sed -n 's/\s*ATTRS{\(\(devnum\)\|\(busnum\)\)}==\"\([^\"]\+\)\"/\4/p' | head -n 2 | awk '{$1 = sprintf("%03d", $1); print}'` | tr " " "/"
Now, if that's not a mouthful, I dunno what is! Let's break it down:
udevadm info --name=/dev/ttyUSB0 --attribute-walk
- returns info about the device and its parent devices
sed -n 's/\s*ATTRS{\(\(devnum\)\|\(busnum\)\)}==\"\([^\"]\+\)\"/\4/p'
- parses these data and returns any lines containing the "devnum" or "busnum" attribute. We'll assume that "busnum" is listed first... and in that case... we can just grab the first two lines of output.
head -n 2
- Grab the first 2 lines of output. We could get more fancy here, but we are just making an assumption that the closest parent's "busnum" and "devnum" are going to be listed first.
awk '{$1 = sprintf("%03d", $1); print}'
- Takes those digits and pads them with zeros.
echo /dev/bus/usb
... - all this jazz is wrapped up into an echo
statement to replace the newlines with spaces. You can add the -n
to echo
if you want to cut off the trailing newline.
tr " " "/"
- replace the spaces in the output with forward slashes
This will output something like:
/dev/bus/usb/001/011
... which, of course, is the device. If you'd like, you can easily output something like busnum:001 devnum:011
with a few tweaks:
echo `udevadm info --name=/dev/ttyUSB0 --attribute-walk | sed -n 's/\s*ATTRS{\(\(devnum\)\|\(busnum\)\)}==\"\([^\"]\+\)\"/\1\ \4/p' | head -n 2 | awk '{$1 = sprintf("%s:%03d", $1, $2); print $1;}'`