11

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.

1
  • 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, 2017 at 22:05

7 Answers 7

26

Use findmnt:

$ findmnt /        
TARGET SOURCE       FSTYPE OPTIONS
/      /dev/md127p1 ext4   rw,relatime,stripe=256,data=ordered
$ findmnt / -o UUID
UUID
046a554b-d9f5-4b23-82e6-ffaeb98284aa
$ findmnt / -o UUID -n
046a554b-d9f5-4b23-82e6-ffaeb98284aa

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.

1
  • 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, 2017 at 20:17
12

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
0
5

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)"
5
  • 2
    This works for me without sudo on 16.04. Sep 30, 2017 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, 2017 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, 2017 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, 2017 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, 2017 at 11:05
4

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

1
  • This works for me but with sudo.
    – pa4080
    Oct 3, 2017 at 23:00
4

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'
1

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.

5
  • 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, 2017 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, 2017 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, 2017 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, 2017 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, 2017 at 15:47
1

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .