How can I get UUID of a volume that contains the / filesystem? The best thing for that I've found to date is blkid -o list. But this output is human readable and hard to parse. Maybe there is a better way?

I need that to parameterize configuration management with system-specific templates.

NOTE about blkid gotcha for those who may reuse outcomes of my question in future: blkid caches results of previous runs at /etc/blkid.tab . That means that running blkid as non-root user first time will not return any data. Also, running blkid as non-root user after root run will return stale (possibly incorrect) data.

  • On my own systems, I assign human readable, unique labels to all partitions. Then I can find out almost anything about them by using their labels and /dev/disk/by-label... This also works for partitions which are not mounted. It has the advantage of being able to write scripts which do things like rsync from root to root-bak which is far less error prone than using 2 UUIDS that don't "mean" anything.
    – Joe
    Oct 5 '17 at 22:05

Use findmnt:

$ findmnt /        
/      /dev/md127p1 ext4   rw,relatime,stripe=256,data=ordered
$ findmnt / -o UUID
$ findmnt / -o UUID -n

It also has several options to control how it looks up information, and how it presents it (including JSON output!). It's part of the mount package, so available on any Ubuntu installation.

  • This works great on 16.04. It failed to function for me on 14.04. I had to use this approach to obtain desired results on trusty.
    – Elder Geek
    Oct 21 '17 at 20:17

Another solution:

lsblk -nr -o UUID,MOUNTPOINT | grep -Po '.*(?= /$)'
  • -n suppresses the header (not really needed, but safer for parsing)
  • -r makes raw output (makes it safer to parse)
  • -o UUID,MOUNTPOINT include only necessary information

You can use the lsblk command to output the UUID, but you need the device name of the partition (such as /dev/sda2). You can get this by using the df command and trimming the output. Use command substitution to give the device name to lsblk. It appears you need sudo to access the UUID, although the normal output of lsblk does not require it:

sudo lsblk -n -o UUID "$(df -P / | tail -n1 | cut -d' ' -f1)"
  • 2
    This works for me without sudo on 16.04. Sep 30 '17 at 2:57
  • only if you (or some script) have ever ran this command as root before. Also, the ouput may be stale (from cache) in this case
    – Dmitriusan
    Sep 30 '17 at 18:15
  • @Dmitriusan I ran this on a 14.04 system that has never had lsblk or blkid run by root and it worked perfectly. Do you know why there would be a caching issue with this command and not with the version posted by Rovo? Does the raw output circumvent caching in some way?
    – Arronical
    Oct 2 '17 at 10:42
  • I think any command that accesses UUID of devices would require root access (including version posted by Rovo). Regarding lsblk, here is a related question unix.stackexchange.com/questions/210889/… (see the first answer)
    – Dmitriusan
    Oct 2 '17 at 10:47
  • I agree that sudo is necessary, but can't find anything to suggest that lsblk relies on caching. Even if I run blkid as root, creating the cache file at /dev/.blkid.tab, non-sudo use of lsblk will not show anything from the UUID column. I don't think there's a risk of stale output.
    – Arronical
    Oct 2 '17 at 11:05

The best solution I managed to come up with is

blkid -o list | awk '/\/[[:space:]]+/{ print $0 }' | tr -s ' ' | cut -d ' ' -f 4

Feels like non-optimal, but works.

Note: [[:space:]] means Space

  • This works for me but with sudo.
    – pa4080
    Oct 3 '17 at 23:00

Adjust the value of mountpoint to the current mount point of the file system in question:

dev="$(exec awk -v mountpoint='/' '($2 == mountpoint){ print $1; quit; }' /proc/mounts)" &&
sudo blkid -o export -- "$dev" | sed -ne 's/^UUID=//p'

Here's what I use:

sudo tune2fs -l $(df  / | tail -1 |awk '{print $1}') |grep UUID|awk '{ print $3 }'

tune2fs is in the e2fsprogs package, which I can't remember if it's installed by default.

sudo apt install e2fsprogs

if it isn't installed.

  • I get awk: not an option: -e I edited your answer to make it functional. If I've overstepped, please feel free to roll it back. Cheers! :-)
    – Elder Geek
    Oct 21 '17 at 20:36
  • Strange, it seems to work with or without the -e for me. -e is documented in the man page for awk. I've always used it in scripts and I was surprised it worked fine without it :) I think -e is an old UNIX habit. But, I should have been consistent in my usage and used -e in either both places or neither place so as not to confuse people.
    – John
    Oct 22 '17 at 22:04
  • Ah, I get the same result as you under 14.04 which uses gawk. I get the error specified under 16.04 which appears to use mawk instead.
    – Elder Geek
    Oct 23 '17 at 14:06
  • It's one of those /etc/alternatives things. /etc/alternatives/awk -> /usr/bin/gawk for me on my 16.04. Mawk is installed, but not active in /etc/alternatives. On my 17.04 gnome it points to awk. On my fresh install 17.10 it's mawk. After installing gawk the link points to gawk, uninstalling gawk returns it to mawk.
    – John
    Oct 24 '17 at 15:17
  • :-) It's these minor differences between supposedly similar programs that likely led to statements like "Less is more"
    – Elder Geek
    Oct 24 '17 at 15:47

Tested to work on 14.04 and 16.04

A simple one-liner that should always produce the UUID of a the root / is

export DRIVE=$(mount | grep ' / ' | awk -F" on " '{print $1}');blkid $DRIVE| cut -d '"' -f2 `

What we are doing here is grepping the output of mount to match the root symbol with spaces on either side / to avoid matching when / is used as a path extension symbol, piping that through awk using " on " as a field separator in order to output only the device name and assigning THAT to the environment variable $DRIVE, then using the output of blkid $DRIVE piped through cut using the " as a field separator and selecting only the second field which strips out everything else, leaving only the UUID.

Note that what belongs after grep in the above command is actually 'space/space' and not '/' as it appears.

This has the benefit of not requiring sudo and will return the appropriate result regardless of how the drive is mounted.

It would be wise to insure that you aren't using the $DRIVE environment variable for anything else prior to attempting this approach echo $DRIVE will return blank line if you aren't using the variable.

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.