I would like to list only the USB storage devices connected to my computer. Since these are SCSI disks, I used the command lsscsi, which lists the USB drives as well as my computer's hard drive and CD drive. Is there a way to ignore the memory storage that's not a USB? I have also tried lsusb, but this includes my keyboard, mouse, and other non-storage devices.
4 Answers
This answer checks the list of all attached block devices and iterates over them with udevadmin to check their respective ID_BUS.
You can see all attached block devices in /sys/block. Here is the bash script from the linked answer that should let you know if it is a USB storage device:
for device in /sys/block/* do if udevadm info --query=property --path=$device | grep -q ^ID_BUS=usb then echo $device fi done I just wrote a function:
dmu() { # Criação : 2019-07-24 RBR. local disks=`lsblk -o name,tran | awk '$2=="usb"{print $1}' | tr "\n" " " | sed -E "s/^ +//g;s/ +$//g"` local mask=`sed -E "s/ /\([\\\\t ]|[0-9]\)+|/g;s/$/\([\\\\t ]|[0-9]\)+/g" <<< ${disks}` lsblk -f | sed -n "1p" lsblk -f | grep -E "$mask" } lsblk --noheadings --nodeps --paths --raw --output NAME,RM,TRAN,TYPE | grep " 1 usb disk$" | cut --delimiter " " --fields 1 Example output:
/dev/sdd /dev/sde /dev/sdf But if your script enjoys zero error tolerance by running with options like
set -euo pipefail (supported in bash, not supported in sh), and grep finds nothing, the script will fail. Use this trick to avoid that:
lsblk --noheadings --nodeps --paths --raw --output NAME,RM,TRAN,TYPE | { grep " 1 usb disk$" || test $? = 1; } | cut --delimiter " " --fields 1 Explanations
lsblk options:
--output NAME,RM,TRAN,TYPE– For each device, print only name, removability, transport type and type. Other device properties don't seem influential in this case.--noheadings– Don't print the header of table, only data.--nodeps– Don't print slaves or holders (like/dev/sda1).--paths– Print complete device path. You probably need/dev/sdbstring, not justsdb. Also, some devices may not be in/devdirectory, so you cannot get a device name and just prefix it with/dev/.--raw– By default, columns of data are aligned for better human perception. With this option, only a single space is used between columns, which is good for grepping.
So, with grep " 1 usb disk$", you literally filter removable USB disks. Examples of unfiltered lsblk output for various devices:
/dev/loop0 0 loop/dev/sda 0 sata diskSATA SSD/dev/sdb 0 sata diskSATA HDD/dev/sdd 1 usb diskUSB flash drive/dev/sr0 1 sata romSATA DVD-RW/dev/sr0 1 usb romUSB DVD-RW
- This answer is very elegant and nice. Thanks a lot - upvoted.Binarus– Binarus2024-04-24 12:20:08 +00:00Commented Apr 24, 2024 at 12:20
You can use lsblk.
lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 465,8G 0 disk ├─sda1 8:1 0 285M 0 part /boot ├─sda2 8:2 0 1,9G 0 part [SWAP] ├─sda3 8:3 0 74,5G 0 part / └─sda4 8:4 0 389,1G 0 part /home sr0 11:0 1 1024M 0 rom Usualy usb devices are on sdb so lsblk sdb should give all usb devices.
- I think this might work. The only thing is that SCSI disks are added in the order that they're mounted and so I'd just have to assume that my hard drive and DVD drive were only sda.Kalmar– Kalmar2015-07-08 21:02:50 +00:00Commented Jul 8, 2015 at 21:02
lsblk -do name,tran | awk '$2=="usb"{print $1}'