I'm not quite certain what you're asking. You mention 'port' several times, but then in your example, you say the answer is /dev/ttyUSB0
, which is a device dev path, not a port. So this answer is about finding the dev path for each device.
Below is a quick and dirty script which walks through devices in /sys
looking for USB devices with a ID_SERIAL
attribute. Typically only real USB devices will have this attribute, and so we can filter with it. If we don't, you'll see a lot of things in the list that aren't physical devices.
#!/bin/bash
for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do
(
syspath="${sysdevpath%/dev}"
devname="$(udevadm info -q name -p $syspath)"
[[ "$devname" == "bus/"* ]] && exit
eval "$(udevadm info -q property --export -p $syspath)"
[[ -z "$ID_SERIAL" ]] && exit
echo "/dev/$devname - $ID_SERIAL"
)
done
On my system, this results in the following:
/dev/ttyACM0 - LG_Electronics_Inc._LGE_Android_Phone_VS930_4G-991c470
/dev/sdb - Lexar_USB_Flash_Drive_AA26MYU15PJ5QFCL-0:0
/dev/sdb1 - Lexar_USB_Flash_Drive_AA26MYU15PJ5QFCL-0:0
/dev/input/event5 - Logitech_USB_Receiver
/dev/input/mouse1 - Logitech_USB_Receiver
/dev/input/event2 - Razer_Razer_Diamondback_3G
/dev/input/mouse0 - Razer_Razer_Diamondback_3G
/dev/input/event3 - Logitech_HID_compliant_keyboard
/dev/input/event4 - Logitech_HID_compliant_keyboard
Explanation:
find /sys/bus/usb/devices/usb*/ -name dev
Devices which show up in /dev
have a dev
file in their /sys
directory. So we search for directories matching this criteria.
syspath="${sysdevpath%/dev}"
We want the directory path, so we strip off /dev
.
devname="$(udevadm info -q name -p $syspath)"
This gives us the path in /dev
that corresponds to this /sys
device.
[[ "$devname" == "bus/"* ]] && exit
This filters out things which aren't actual devices. Otherwise you'll get things like USB controllers & hubs. The exit
exits the subshell, which flows to the next iteration of the loop.
eval "$(udevadm info -q property --export -p $syspath)"
The udevadm info -q property --export
command lists all the device properties in a format that can be parsed by the shell into variables. So we simply call eval
on this. This is also the reason why we wrap the code in the parenthesis, so that we use a subshell, and the variables get wiped on each loop.
[[ -z "$ID_SERIAL" ]] && exit
More filtering of things that aren't actual devices.
echo "/dev/$devname - $ID_SERIAL"
I hope you know what this line does :-)
/dev
with an entry inlsusb
? Or do you want to list all devices in/dev
that are derived from a physical USB device? Or are you just wantingls /dev/ttyUSB*
?ls /dev/ttyUSB*
will only list maybee 10 ports but from this list I cannot tell which one is for my device.