113

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?

Chinna
  • 3,930
  • 4
  • 25
  • 55
warren
  • 32,620
  • 21
  • 85
  • 124
  • Since you talk about them maybe being mounted, I guess you want a list of partitions, not just of disks? – Mark Baker Oct 14 '08 at 12:48
  • partitions are fine, too, yes :) .. if I know the partitions, I'll also know what physical devices are available – warren Oct 14 '08 at 13:01
  • 2
    since [Unix & Linux](http://unix.stackexchange.com) is now available, this question should be migrated there – warren Oct 02 '12 at 14:14
  • @warren - it's a generally accepted rule not to migrate old questions, especially not ones that are 4 years old. – ChrisF Oct 03 '12 at 15:01
  • @ChrisF - where is that rule outlined? I've had some old questions migrated elsewhere previously. – warren Oct 03 '12 at 15:24
  • @warren - It's mentioned on MSO in a few places, plus (as these sorts of migrations would require moderator intervention) it's something that's come up in discussion quite a few times. – ChrisF Oct 03 '12 at 15:27
  • @ChrisF - sounds like there's no point in closing old, now-off-topic questions, then, if they're not going to be put where they "belong" :( – warren Oct 03 '12 at 15:31
  • 3
    @warren - oh no. They still should be closed. As you as the post owner want this moved you should flag it for moderator attention. The fact that you want it moved will carry some weight. – ChrisF Oct 03 '12 at 15:39
  • @warren - alternatively (and perhaps a better solution) would be to repost. This avoids having any "bad" answers migrated and ensures that the voting on the question is in keeping with the new site. – ChrisF Oct 03 '12 at 15:50
  • @warren Speaking as a heavy user of [unix.se]: this question would be a perfect fit for U&L, but the existing answers aren't outstanding, and the voting on them is no good. It should not be migrated. More generally, this determination needs to be made on a case-by-case basis, by the target community. – Gilles 'SO- stop being evil' Oct 03 '12 at 16:00
  • Use [libsysfs](http://linux-diag.sourceforge.net/Sysfsutils.html), the recommended way to query the kernel about attached devices of all kinds. – David Schmitt Oct 14 '08 at 12:41
  • @Gilles - asked: http://unix.stackexchange.com/q/49786/6388 – warren Oct 03 '12 at 16:46
  • `df -h` worked for me when others didn't. – cprcrack May 13 '14 at 08:55
  • @cprcrack - that doesn't even come close to what is described in this question – warren Jan 29 '19 at 14:17

7 Answers7

81

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

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Steve Baker
  • 4,323
  • 1
  • 20
  • 15
  • 4
    This ommits CD/DVD drives for example (I know they're usually not writable) – pixelbeat Oct 14 '08 at 21:24
  • There's kind of a limit on what you can do from a shell. Most of the other suggestions that are higher rated either don't work from a shell, won't work unless dbus is running, or will list devices that aren't actually present/configured. This is just faster than checking all the /dev devices. – Steve Baker Oct 17 '08 at 20:28
  • 5
    lsblk this one is better – emj365 Dec 10 '13 at 18:24
  • 1
    /proc/partitions gives you the drive letter in Cygwin, too. – katriel May 02 '15 at 18:48
73

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.

Maxim Veksler
  • 29,272
  • 38
  • 131
  • 151
  • 9
    Not sure if you ever worked out how `fdisk -l` works, but I thought you might like to know: it reads `/proc/partitions` and then iterates through `/sys/dev/block/*` which contains a set of symlinks to the devices' true repr in sysfs. You can find this information out by running `fdisk` under `strace` :) –  Feb 16 '13 at 16:48
  • 1
    Great! Thanks. (OT: Sucks to see this question locked. There should be a "vote to revert the lock" button). – Maxim Veksler Feb 17 '13 at 03:18
  • 1
    there is for users of 3k rep and higher (a "reopen" button). –  Feb 17 '13 at 16:05
  • oh really? Then I must get to 3k as fast as possible. – Maxim Veksler Feb 19 '13 at 13:43
  • yep, see the [privileges page](http://stackoverflow.com/privileges) for the full list of things you can do with more rep. –  Feb 19 '13 at 14:01
  • You can also use [Parted](https://www.gnu.org/software/parted/): `parted -l`. This may be necessary if your disk using [GPT](https://en.wikipedia.org/wiki/GUID_Partition_Table). – Andrew Marshall Jan 19 '14 at 21:57
35

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)
THESorcerer
  • 989
  • 9
  • 19
9

ls /sys/block

Mihai Limbășan
  • 64,368
  • 4
  • 48
  • 59
  • doesn't list partitions. I'm not sure whether that's what the original question wanted or not. – Mark Baker Oct 14 '08 at 12:47
  • 1
    I never knew about /sys/block - though it also lists devices that are not writable, like the DVD drive – warren Oct 14 '08 at 13:02
  • 1
    Indeed it doesn't list partitions - you can check the subdirectories though, looking for all subdirs holding at minimum files named "dev", "stat" and "uevent" and subdirs named "holders". DVDs are still storage class devices :) – Mihai Limbășan Oct 14 '08 at 13:21
  • 3
    moocha, why don't you expand your answer a bit? – SpoonMeiser Oct 15 '08 at 19:54
  • 2
    @warren - presumably /dev/dvd will just be an alias for a /dev/sd* or /dev/hd* device, so you would have had this problem anyway. – SpoonMeiser Oct 15 '08 at 19:55
  • try `lsblk`, this will list disk devices, and returns your a intuitive output. – coanor Jul 17 '15 at 00:51
7

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
ZungBang
  • 409
  • 2
  • 8
4

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.

Mark Baker
  • 5,588
  • 2
  • 27
  • 25
2

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.

Mark Baker
  • 5,588
  • 2
  • 27
  • 25