Find all storage devices attached to a Linux machine

LinuxBashShell

Linux Problem Overview


I have a need to find all of the writable storage devices attached to a given machine, whether or not they are mounted.

The dopey way to do this would be to try every entry in /dev that corresponds to a writable devices (hd* and sd*)......

Is there a better solution, or should I stick with this one?

Linux Solutions


Solution 1 - Linux

/proc/partitions will list all the block devices and partitions that the system recognizes. You can then try using file -s <device> to determine what kind of filesystem is present on the partition, if any.

Solution 2 - Linux

You can always do fdisk -l which seems to work pretty well, even on strange setups such as EC2 xvda devices.

Here is a dump for a m1.large instance:

root@ip-10-126-247-82:~# fdisk -l

Disk /dev/xvda1: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/xvda1 doesn't contain a valid partition table

Disk /dev/xvda2: 365.0 GB, 365041287168 bytes
255 heads, 63 sectors/track, 44380 cylinders, total 712971264 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/xvda2 doesn't contain a valid partition table

Disk /dev/xvda3: 939 MB, 939524096 bytes
255 heads, 63 sectors/track, 114 cylinders, total 1835008 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/xvda3 doesn't contain a valid partition table

While mount says:

root@ip-10-126-247-82:~# mount
/dev/xvda1 on / type ext4 (rw)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
fusectl on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/xvda2 on /mnt type ext3 (rw)

And /proc/partitions says:

root@ip-10-126-247-82:~# cat /proc/partitions
major minor  #blocks  name

 202        1   10485760 xvda1
 202        2  356485632 xvda2
 202        3     917504 xvda3

Side Note

How fdisk -l works is something I would love to know myself.

Solution 3 - Linux

you can also try lsblk ... is in util-linux ... but i have a question too

fdisk -l /dev/sdl

no result

grep sdl /proc/partitions      
   8      176   15632384 sdl
   8      177   15628288 sdl1

lsblk | grep sdl
sdl       8:176  1  14.9G  0 disk  
`-sdl1    8:177  1  14.9G  0 part  

fdisk is good but not that good ... seems like it cannot "see" everything

in my particular example i have a stick that have also a card reader build in it and i can see only the stick using fdisk:

fdisk -l /dev/sdk

Disk /dev/sdk: 15.9 GB, 15931539456 bytes
255 heads, 63 sectors/track, 1936 cylinders, total 31116288 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xbe24be24

   Device Boot      Start         End      Blocks   Id  System
/dev/sdk1   *        8192    31116287    15554048    c  W95 FAT32 (LBA)

but not the card (card being /dev/sdl)

also, file -s is inefficient ...

file -s /dev/sdl1
/dev/sdl1: sticky x86 boot sector, code offset 0x52, OEM-ID "NTFS    ", sectors/cluster 8, reserved sectors 0, Media descriptor 0xf8, heads 255, hidden sectors 8192, dos < 4.0 BootSector (0x0)

that's nice ... BUT

fdisk -l /dev/sdb
/dev/sdb1            2048   156301487    78149720   fd  Linux raid autodetect
/dev/sdb2       156301488   160086527     1892520   82  Linux swap / Solaris

file -s /dev/sdb1
/dev/sdb1: sticky \0

to see information about a disk that cannot be accesed by fdisk, you can use parted:

parted /dev/sdl print

Model: Mass Storage Device (scsi)
Disk /dev/sdl: 16.0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type     File system  Flags
 1      4194kB  16.0GB  16.0GB  primary  ntfs




arted /dev/sdb print 
Model: ATA Maxtor 6Y080P0 (scsi)
Disk /dev/sdb: 82.0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type     File system     Flags
 1      1049kB  80.0GB  80.0GB  primary                  raid
 2      80.0GB  82.0GB  1938MB  primary  linux-swap(v1)

Solution 4 - Linux

ls /sys/block

Solution 5 - Linux

Using HAL (kernel 2.6.17 and up):


#! /bin/bash
hal-find-by-property --key volume.fsusage --string filesystem |
while read udi ; do
# ignore optical discs
if [[ "$(hal-get-property --udi $udi --key volume.is_disc)" == "false" ]]; then
dev=$(hal-get-property --udi $udi --key block.device)

fs=$(hal-get-property --udi $udi --key volume.fstype)
echo $dev": "$fs
fi
done

Solution 6 - Linux

Modern linux systems will normally only have entries in /dev for devices that exist, so going through hda* and sda* as you suggest would work fairly well.

Otherwise, there may be something in /proc you can use. From a quick look in there, I'd have said /proc/partitions looks like it could do what you need.

Solution 7 - Linux

libsysfs does look potentially useful, but not directly from a shell script. There's a program that comes with it called systool which will do what you want, though it may be easier to just look in /sys directly rather than using another program to do it for you.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwarrenView Question on Stackoverflow
Solution 1 - LinuxSteve BakerView Answer on Stackoverflow
Solution 2 - LinuxMaxim VekslerView Answer on Stackoverflow
Solution 3 - LinuxTHESorcererView Answer on Stackoverflow
Solution 4 - LinuxMihai LimbășanView Answer on Stackoverflow
Solution 5 - LinuxZungBangView Answer on Stackoverflow
Solution 6 - LinuxMark BakerView Answer on Stackoverflow
Solution 7 - LinuxMark BakerView Answer on Stackoverflow