28

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?

2
  • 6
    It 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). Commented Jan 4, 2013 at 16:14
  • In 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...
    – atomAltera
    Commented Jan 8, 2013 at 1:52

8 Answers 8

26

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...

12

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 eveneasybashbui`.

#!/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):

dialog preview

Replacing dialog by gdialog (on line 24) give:

gdialog previw

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
17
  • I 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.
    – MountainX
    Commented Mar 12, 2014 at 2:21
  • Ok, I will post explanation. If you find what wrong, please let me know... Commented Mar 12, 2014 at 7:15
  • @MountainX I've tested this under ubuntu 12-04 LTS just now, this worked fine! Commented Mar 12, 2014 at 7:55
  • @MountainX Ok: on Ubuntu you have to replace dialog on line 24 by gdialog. Commented Mar 12, 2014 at 8:39
  • @f-hauri - thanks! I will test it later today.
    – MountainX
    Commented Mar 12, 2014 at 13:18
9

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.

1
  • Definitely the easiest. Just do ls -l /dev/disk/by-label/ or /by-path/ to get the entire mapping.
    – Izkata
    Commented Jan 5, 2013 at 5:11
7

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.

3

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.

2

It's very likely your system drive is sda given the big number of partitions. To make sure of that, you could use the output of mount, df -h or lsblk and look for where / is located. Avoid that drive.

Other than that, both sdb and sdc are valid candidates. Mounting them and looking at the contents is the safest way. What could be quicker is as simple as pulling the stick and watching which one disappears (or comparing to the output of dmesg after reinserting it (it should tell you which /dev/ name it got)

1

My favorite, assuming the drive is not needed to keep the system running, is to compare directory listing with and without the USB drive in the system.

1

One simple way is to look in /dev/disk/by-id/ - it contains a symlink farm pointing to all the actual drive and partition device nodes in the system. The symlink names identify the drive interface type, brand & model, and serial number, and can be used as a persistent unique identifier for each drive.

For example

$ ls -lF /dev/disk/by-id/usb-Generic_Flash_Disk*
lrwxrwxrwx 1 root root  9 Jan  5 11:10 /dev/disk/by-id/usb-Generic_Flash_Disk_CAAE91F7-0:0 -> ../../sdo
lrwxrwxrwx 1 root root 10 Jan  5 11:10 /dev/disk/by-id/usb-Generic_Flash_Disk_CAAE91F7-0:0-part1 -> ../../sdo1

this looks a lot better on a wide-column terminal of course :)

I find the following alias useful for getting a quick listing of all disks (but not partitions) in the system:

alias list_disks='ls -lF /dev/disk/by-id/{scsi,usb}-* | grep sd.$'

I would have included example output from my home zfsonlinux fileserver but it looks really ugly here, the text field width is nowhere near wide enough.

1
  • Thanks @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.
    – qneill
    Commented Aug 22, 2015 at 22:02

Not the answer you're looking for? Browse other questions tagged .