Detecting Unmounted Partitions With Blkid

Did you know that you can instantly check all partitions on your system (including USB thumb drives), and see if they’re mounted or not? The hero command of the day is sudo blkid -o list:

$ sudo blkid -o list
device       fs_type label    mount point      UUID
-----------------------------------------------------------------------------------
/dev/sda1    ntfs             /mnt/windows-xp  XXXXXXXXXXXXXXXX
/dev/sda2    ext4             /                XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/dev/sda3    ext4             /home            XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/dev/sda6    swap             <swap>           XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/dev/sda5    ext4             /mnt/data        XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/dev/sdb1    ext2             (not mounted)    XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/dev/sdc1    vfat             (not mounted)    XXXX-XXXX

As you can see, I have two USB drives (one in ext2 and the other in vfat format) plugged in, but not mounted, and blkid detects this for me. Pretty useful, don’t you think? There’s no need to parse /proc/mounts or fiddle with the (very) verbose output of sudo fdisk -l. I stumbled upon blkid’s obscure “-o list” option while trying to write a shell script to automatically mount unmounted USB drives.

The only troublesome aspects of “-o list” are that you can’t customize which columns are displayed (e.g., for me, I’d like to drop the label column), and also you can’t separate the columns by whitespace because of how there is a space inside the (not mounted) mount point. Looking at the sources for blkid, it seems that there are also two other descriptions with whitespace in them: (in use) and (mounted, mtpt unknown) (see http://git.kernel.org/?p=utils/util-linux-ng/util-linux-ng.git;a=blob_plain;f=misc-utils/blkid.c;hb=HEAD). These deficiencies make it hard to easily and reliably parse the output with just a shell script.

I actually ended up writing a 300 line Haskell program that uses Parsec to reliably parse the output of blkid. It took a while to write, considering my newbie Haskell skills (aren’t most Haskellers late bloomers?). Anyway, it also leverages the CmdArgs library, and automatically mounts/unmounts USB devices with ease and grace. Speaking of Haskell, I’m slowly in the process of converting my various error-prone shell scripts into robust, mini Haskell programs, and I’ve been very satisfied with the results. And porting shell scripts into Haskell is a great way to learn more Haskell, too!

UPDATE December 1, 2011: Here is a convenience link to said ~300 line program for you Googlers: Parsec and CmdArgs in Action: A Small Example.

UPDATE December 11, 2011: Fixed broken link. Also, the recent kernel.org fiasco has changed the home of util-linux-ng to: https://github.com/karelzak/util-linux/, and the blkid source is at https://github.com/karelzak/util-linux/blob/master/misc-utils/blkid.c.