Let's suppose you have two hard-disks:

  • one internal (boots GNU/Linux (Debian));

  • one external (USB).

fdisk -l detects both, but will not tell you which is /dev/sda and which is /dev/sdb. lsusb will tell you there is an external USB device connected, but will not tell you whether it has been mapped to /dev/sda or /dev/sdb.

How can you be get such information from your system?

ls -l /sys/class/block/sd?

The sd? entries are symbolic links that show how the disk is connected to the computer. There'll be a /usb in there for a USB disk.

udevadm info -a -n sda

This shows all the identifying information the kernel can get at directly for sda. You'll see how the disk is connected in more detail, e.g. going directly from SUBSYSTEMS=="scsi" to SUBSYSTEMS=="pci", DRIVERS=="ahci" for a SATA disk on an Intel controller, or going from SUBSYSTEMS=="scsi" to SUBSYSTEMS=="usb", DRIVERS=="usb-storage" for an USB disk.

ls -l /dev/disk/by-*

Under /dev/disk/by-*, you can locate disks by hardware attachment (by-path), by some globally unique identifier (by-uuid), by human-chosen label (by-label), or by manufacturer identification (by-id).

  • "ls -l /sys/class/block/sd?" is what I was after. Thank you. – Eleno Jul 17 '12 at 14:04

On my Debian box (now on Lubuntu), I often used to use testdisk -l (read: 'minus small L') for this purpose. I am aware that not every distro has testdisk (a well-known recovery tool) pre-installed, but most ought to have it.

Another great tool which I learned not long ago is lsblk:

$ lsblk -d -io KNAME,TYPE,SIZE,MODEL

or, if you only want your HDDs to show:

$ lsblk -d -io KNAME,TYPE,SIZE,MODEL | grep 'sd\w'

(The \w, albeit not mandatory, will avoid ugly "half-colored" output on distros that in default configuration have grep aliased to grep --color=auto.)

You may also use my (in reality very complex) script which I've decided to trim down to serve only this one little purpose:



I'm not sure of the best answer, but here are some ideas:

You can look at /sys/class/block/sdX/device/model to get the make/model information reported by the device. For example:

cat /sys/class/block/sda/device/model 

This by itself might be enough to identify which one is your external and which one is your internal device. You can look at the output from dmesg, which for USB devices will include something like:

[ 2073.412999] scsi12 : usb-storage 2-1.8:1.0

This identifies identifies SCSI bus 12 as a USB storage bus. We can then look for SCSI devices on bus 12:

# dmesg | grep scsi12
[ 2074.488651] sd 12:0:0:0: Attached scsi generic sg6 type 0
[ 2076.592154] sd 12:0:0:0: [sdf] 30481152 512-byte logical blocks: (15.6 GB/14.5 GiB)
[ 2076.592639] sd 12:0:0:0: [sdf] Write Protect is off
[ 2076.592645] sd 12:0:0:0: [sdf] Mode Sense: 23 00 00 00
[ 2076.593142] sd 12:0:0:0: [sdf] No Caching mode page present
[ 2076.593147] sd 12:0:0:0: [sdf] Assuming drive cache: write through
[ 2076.596270] sd 12:0:0:0: [sdf] No Caching mode page present
[ 2076.596276] sd 12:0:0:0: [sdf] Assuming drive cache: write through
[ 2076.619078] sd 12:0:0:0: [sdf] No Caching mode page present
[ 2076.619084] sd 12:0:0:0: [sdf] Assuming drive cache: write through
[ 2076.619088] sd 12:0:0:0: [sdf] Attached SCSI removable disk

Often the quickest is just to cat /proc/scsi/scsi, which will have enough to show you which is which:

$ cat /proc/scsi/scsi 
Attached devices:
Host: scsi2 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: ST95005620AS     Rev: SD23
  Type:   Direct-Access                    ANSI  SCSI revision: 05
Host: scsi4 Channel: 00 Id: 00 Lun: 00
  Vendor: 2.0      Model: USB Flash Drive  Rev: 1.00
  Type:   Direct-Access                    ANSI  SCSI revision: 02

So, in my case, the first (which would be sda) is a Seagate ST95005620AS, and the second (sdb) is a USB Flash Drive.

To get more detailed and specific info, look in /sys/block/sda and /sys/block/sdb, and also /sys/class/scsi_disk.

/sys/class/scsi_disk in particular contains symlinks into the PCI address tree which will reveal USB vs SATA hosts:

$ ls -l /sys/class/scsi_disk
total 0
lrwxrwxrwx 1 root root 0 2012-02-28 23:50 2:0:0:0 -> ../../devices/pci0000:00/0000:00:1f.2/host2/target2:0:0/2:0:0:0/scsi_disk/2:0:0:0
lrwxrwxrwx 1 root root 0 2012-02-28 23:50 4:0:0:0 -> ../../devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0/4:0:0:0/scsi_disk/4:0:0:0
$ cat /sys/block/sd[ab]/device/model
USB Flash Drive 

For more info, try also, find /sys -name 'scsi*' and find /sys/block/sd[a-z]/.


Gilles' answer I think is the best, but I'm adding this one just for the sake of completeness.

hdparm -i /dev/sda

This will show you some basic info the controller driver obtained from the drive (including model and serial number). This command does not require root if you have read access to the /dev device (like via group permissions).

hdparm -I /dev/sda

This will show you a ton of advanced information about the drive (model, serial number, and everything possible). This command does require root.


The two commands that I normally use in situations like this are lsblk and blkid. The former will output each disk block device with a list of partitions, their size, and their mountpoint (if mounted) (and maybe their volume labels, if present, although I haven't got any devices with volume labels connected at the moment to check this with). The latter will output each partition with its filesystem type, UUID, and volume label (if present).

mount will also tell you where each device is mounted, so the device mounted at the filesystem root is the boot device. I believe internal hard drives are also enumerated before external hard drives, so /dev/sda should be the internal hard drive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.