How to determine which sd* is usb?
Solution 1
Assuming you're on Linux.
Try:
sudo /lib/udev/scsi_id --page=0x80 --whitelisted --device=/dev/sdc
or:
cat /sys/block/sdc/device/{vendor,model}
You can also get information (including labels) from the filesystems on the different partitions with
sudo blkid /dev/sdc1
The pathid will help to determine the type of device:
readlink -f /sys/class/block/sdc/device
See also:
find /dev/disk -ls | grep /sdc
Which with a properly working udev
would give you all the information from the other commands above.
The content of /proc/partitions
will give you information on size (though not in as a friendly format as lsblk
already mentionned by @Max).
sudo blockdev --getsize64 /dev/sdc
Will give you the size in bytes of the corresponding block device.
sudo smartctl -i /dev/sdc
(cross-platform), will also give you a lot of information including make, model, size, serial numbers, firmware revisions...
Solution 2
Finalized bash sample
There is a little part of a script I wrote to create and install live usb key, (dual boot ubuntu - debian):
The very first part USBKEYS=...
is the answer to this question
In short, this:
list removable devices, driven by
sd
and having non zero size.
Note This script use dialog
which seem not installed by default on Ubuntu. But dialog
could be replaced by gdialog
, whiptail
or 'zenityor even
easybashbui`.
#!/bin/bash
export USBKEYS=($(
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd |
sed s/device.uevent.*$/size/ |
xargs grep -Hv ^0$ |
cut -d / -f 4
))
export STICK
case ${#USBKEYS[@]} in
0 ) echo No USB Stick found; exit 0 ;;
1 ) STICK=$USBKEYS ;;
* )
STICK=$(
bash -c "$(
echo -n dialog --menu \
\"Choose wich USB stick have to be installed\" 22 76 17;
for dev in ${USBKEYS[@]} ;do
echo -n \ $dev \"$(
sed -e s/\ *$//g </sys/block/$dev/device/model
)\" ;
done
)" 2>&1 >/dev/tty
)
;;
esac
[ "$STICK" ] || exit 0
echo $STICK...
Sample (I've just connected 3 USB sticks -- in addition to my 3 hard disks):
Replacing dialog
by gdialog
(on line 24) give:
But the syntax could be used with other dialog utility, like whiptail
...
Essential part
export USBKEYS=($(
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd |
sed s/device.uevent.*$/size/ |
xargs grep -Hv ^0$ |
cut -d / -f 4
))
for dev in ${USBKEYS[@]} ;do
echo $dev \"$(
sed -e s/\ *$//g </sys/block/$dev/device/model
)\" ;
done
sdd "Storage Media"
sde "Freecom Databar"
sdf "silicon-power"
Detailed explanation
This use some bashisms:
export USBKEYS=($( # Declaration of *array* 'USBKEYS'
grep -Hv ^0$ /sys/block/*/removable | # search for *not 0* in `removable` flag of all devices
sed s/removable:.*$/device\\/uevent/ | # replace `removable` by `device/uevent` on each line of previous answer
xargs grep -H ^DRIVER=sd | # search for devices drived by `SD`
sed s/device.uevent.*$/size/ | # replace `device/uevent` by 'size'
xargs grep -Hv ^0$ | # search for devices having NOT 0 size
cut -d / -f 4 # return only 4th part `/` separated
))
for dev in ${USBKEYS[@]} ;do # for each devices in USBKEY...
echo $dev \"$(r # echo device name and content of model file
sed -e s/\ *$//g </sys/block/$dev/device/model
)\" ;
done
After having inserted three usb sticks on my desk:
grep -H . /sys/block/*/removable
/sys/block/loop0/removable:0
/sys/block/loop1/removable:0
...
/sys/block/sdc/removable:0
/sys/block/sdd/removable:1
/sys/block/sde/removable:1
/sys/block/sdf/removable:1
/sys/block/sr0/removable:1
(Yes my desk hold 3 physical hard drives: sda
, sdb
and sdc
. First removable become sdd
and sde
).
So:
grep -Hv ^0$ /sys/block/*/removable
/sys/block/sdd/removable:1
/sys/block/sde/removable:1
/sys/block/sdf/removable:1
/sys/block/sr0/removable:1
I have the list of removable devices,
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/
/sys/block/sdd/device/uevent
/sys/block/sde/device/uevent
/sys/block/sdf/device/uevent
/sys/block/sr0/device/uevent
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd
/sys/block/sdd/device/uevent:DRIVER=sd
/sys/block/sde/device/uevent:DRIVER=sd
/sys/block/sdf/device/uevent:DRIVER=sd
I have the list of removable devices that driven by sd
driver (i.e., not sr
, nor floppy
)
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd |
sed s/device.uevent.*$/size/
/sys/block/sdd/size
/sys/block/sde/size
/sys/block/sdf/size
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd |
sed s/device.uevent.*$/size/ |
xargs grep -Hv ^0$
/sys/block/sdd/size:15224832
/sys/block/sde/size:7834944
/sys/block/sdf/size:7831552
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd |
sed s/device.uevent.*$/size/ |
xargs grep -Hv ^0$ |
cut -d / -f 4
sdd
sde
sdf
Also:
export USBKEYS=($(
grep -Hv ^0$ /sys/block/*/removable |
sed s/removable:.*$/device\\/uevent/ |
xargs grep -H ^DRIVER=sd |
sed s/device.uevent.*$/size/ |
xargs grep -Hv ^0$ |
cut -d / -f 4
))
set | grep ^USBKEYS=
USBKEYS=([0]="sdd" [1]="sde" [2]="sdf")
And finally:
cat /sys/block/$USBKEYS/device/model
Storage Media
cat /sys/block/${USBKEYS[2]}/device/model
silicon-power
but
printf "|%s|\n" "$(</sys/block/$USBKEYS/device/model)"
|Storage Media |
It's because I wrote:
echo ${USBKEYS[2]} \"$(sed -e s/\ *$//g </sys/block/${USBKEYS[2]}/device/model)\"
sde "silicon-power"
Shrinked - golfed:
There is a shortened version
US=($(cut -d/ -f4 <(grep -vl ^0$ $(sed s@device/.*@size@ <(grep -l ^DRIVER=sd $(
sed s+/rem.*$+/dev*/ue*+ <(grep -Hv ^0$ /sys/block/*/removable)) <(:))) <(:))))
(Nota: <(:)
do pseudo empty file by fork to :
this is shorter than /dev/null
but not really equivalent)
Two lines and one variable UsbSticks
holding:
set | grep ^US=
US=([0]="sde" [1]="sdf" [2]="sdg")
So the (begin of my) script could become:
#/bin/bash
US=($(cut -d/ -f4 <(grep -vl ^0$ $(sed s@device/.*@size@ <(grep -l ^DRIVER=sd $(
sed s+/rem.*$+/dev*/ue*+ <(grep -Hv ^0$ /sys/block/*/removable)) <(:))) <(:))))
case ${#US[@]} in 0)echo "No USB stick found.";exit 0;;1)S=$US;;*)S=$(sh -c "$(
sed -nre 's@/sys/block/(.*)/device/model:(.*)$@\1 "\2"@;H;${x;s/\n/ /g;
s/^/whiptail --menu "Choose an USB stick" 22 76 14/;p}' <(grep -H . $(
printf /sys/block/%s/device/model\\n ${US[@]})))" 2>&1 >/dev/tty) ;; esac
whiptail --defaultno --yesno "Could I destroy content of $S!?" 10 70 6 || exit 0
Solution 3
On recent version of Linux, there are /dev/disk/by-{id,label,path,uuid}
directories that contain automagic symlinks to the various /dev/sdX and /dev/sdXN entries (I believe all of these are setup by udev). These provide more stable and informative names for your disks and partitions. I find /dev/disk/by-label/
the most useful (especially if you label your filesystem partitions), but by-path
may be more useful for your use case.
Solution 4
udev
knows your system. so you can get info through udevadm
, under /sys/
like this (run as root, or with sudo depending on your distro)
udevadm info -a -p /sys/block/sdb
udevadm info -a -p /sys/block/sdc
reading through the output you'll come across some meaningful results, such as
ATTRS{vendor}
ATTRS{model}
you should be able to get some info about which one is the usb. additionally the variable
SUBSYSTEM=="usb"
should give you a nice big hint that we are talking about a usb.
then read the KERNEL
variable to understand which sd* device is the usb.
Other commands that can be of help, are lshw
that lists all your hardware by connection, lsusb
which lists usb devices but doesn't show the sd* letter that has been provided.
Also dmesg
will give you all the necessary info if you type it just after you connect the usb to your computer.
These are all CLI commands, if your prefer something more GUI like some other lad will be able to help you more in that direction.
Solution 5
You can also use lsscsi
command which prints various information about attached SCSI devices (obtained from /proc and /sys). You're interested in the transport info, so lsscsi -t | grep usb
will tell you which device is using USB transport.
Related videos on Youtube
Benny Abramovici
Developer who enjoys sharing knowledge. https://ksharma.dev Open source projects: Github
Updated on September 18, 2022Comments
-
Benny Abramovici over 1 year
Possible Duplicate:
How to know if /dev/sdX is a connected USB or HDD?The output of
ls /dev/sd*
on my system is -sda sda1 sda2 sda3 sda4 sda5 sda6 sda7 sdb sdc sdc1 sdc2
How should I determine which drive is which?
-
TheMeaningfulEngineer over 11 yearsIt is maybe worth mentioning that devices without numbers are discs (sda, sdb, sdc), and with numbers are partitions on that disc (sda1,sda2...,sdc1,sdc2).
-
atomAltera over 11 yearsIn debain I use df command, it displays me mounted devices (my debian mounts flash drives automatically when it plugged in) From which flash drive mounted to /media/usb. You can use mount command instant...
-
-
Izkata over 11 yearsDefinitely the easiest. Just do
ls -l /dev/disk/by-label/
or/by-path/
to get the entire mapping. -
Jarek about 10 yearsI couldn't get this to work on Ubuntu 12.04. Could you add an explanation for how the bash code is supposed to work? Maybe then I can figure out why it isn't working for me. Thanks.
-
F. Hauri about 10 yearsOk, I will post explanation. If you find what wrong, please let me know...
-
F. Hauri about 10 years@MountainX I've tested this under ubuntu 12-04 LTS just now, this worked fine!
-
F. Hauri about 10 years@MountainX Ok: on Ubuntu you have to replace
dialog
on line 24 bygdialog
. -
Jarek about 10 years@f-hauri - thanks! I will test it later today.
-
mikeserv about 10 yearslsblk -o tran,name,mountpoint would probably be a lot less work.
-
F. Hauri about 10 years@mikeserv Not sure! And in fine, your sample don't work.
-
F. Hauri about 10 years@mikeserv
tran
don't work in my Debian, and this don't tell if device is removable or not, if it is a cdrom (sata) or a card reader host... You're totaly wrong. -
mikeserv about 10 yearsOk, probably it's older kernel - that's what Debian is known for. But surely, you can lsblk -o rm,name,mountpoint, yes? And besides, that should definitely trim the posssibilities from "who knows?" to two or three to
stat
in a for loop, yes? -
mikeserv about 10 yearsJust do lsblk --help. blockdev --help. findmnt --help. There's way more info in there than I'm gonna give you here.
-
F. Hauri about 10 yearsThanks, I've already read all this stuff, but my previous answer stay: This don't give you a limited list of removable devices that not empty card reader... Or you have use this tools with strong syntax, and you have to
grep
orsed
anyway. This stuf is recent (won't work under Debian 6, for sample) and work more or less in same way I manually do. At begin of my answer, I've explained that I use this already from some time. -
mikeserv about 10 yearsNo, those are standard linux utils built around the standard libblkid Linux C library. These are tools built for this purpose by the people that maintain the kernel code that makes them work. They don't do what you manually do. And besides, I barely scratched the surface on the amount of information they can give you - just read the
man
pages. -
mikeserv about 10 yearsAnd you don't have to grep or sed anything - just read the --help and it will tell you how to simply pull your desired information in key=value pairs. For stat, lsblk, blkid, blockdev, findmnt, etc.
-
F. Hauri about 10 years
-
Jarek about 10 years@F.Hauri-could you fix the formatting of the last code block in your answer. And thanks for the great answer! (I'm hoping to get it to work for me.)
-
mikeserv about 10 yearsIt doesnt register as removable? Weird - Hauri and I worked it out together - that was one of the dependencies he set.
-
mikeserv about 10 yearsAt this point you'll just have to
grep
for the identifying keys you need. That's why I tried to provide it broken down in the other answer so you could see at what stage the available data was getting pared away. -
qneill over 8 yearsThanks @cas, this helped me verify what I was seeing in dmesg. I was trying to fix a flash drive (marked as corrupted by Windows) using the camera+usb cable. It was not showing up in the device list; dmesg suggested '/dev/sde' but fdisk showed nothing. Using /dev/disk/by-id showed it, will have to remember this one.