I have been working on a bash scripting project to auto build Linux from scratch. Every time I go through the code I find way to make it cleaner. I take a little section of code and make it better.
The other day I was making a modification to check if a filesystem is mounted before mounting it. I was looking for a better way to do so. I did not want to use the usual mount | grep or any code like it. I wanted something cleaner.
Mount vs Findmnt
I don’t know why, but at that moment I found myself wondering why I connect to the internet so often to find information that is already on my laptop. So, I fire up man mount, I quickly glanced at the man page and notice this:
And there I had my answer. First I have been using the wrong command for a while now. Second, Google does not always have the best answer.
The irony here is that this is not mentioned in online man pages that I usually look through. See for yourself, on the man page of mount, findmnt is only referenced at the end. Should I have gone through my regular channels to find an answer I would not be writing this article.
Right away I got very curious, how much better is this findmnt? How many pipes will I be able to remove from my scripts? Turns out it is so much better then mount listing. First, lets compare the default output of each command.
Mount default output
Looking at the above listing of mounted file system, it is easy to see why grep became so popular. The information is all there, but a better format would make it easier to read. To accomplish that, you already would need a pipe and external command. Now let’s look at findmnt.
Findmnt default output
That looks a lot better. It gets better, with findmnt you won’t have to use a combination of tools anymore. It is very flexible and that gives you a chance to write cleaner code when used in a script.
Practical usage of findmnt command in Linux
Checking if a file system is mounted with findmnt is much easier. You can check for a source or target without using any options. Provide a mount point (target) or device (source) with no option and findmnt will attempt to match the argument you provided against both.
Findmnt really works like a search command for file system. If matches are found, they will be printed and findmnt returns 0. When nothing matches your query, findmnt prints nothing and returns 1.
A long list of options comes with findmnt. You have 2 main category of options, narrowing your search and formatting the output.
Narrowing your search
Like find for finding files, findmnt is for finding file system. You already know how to limit your search by providing a string that will be matched against SOURCE and TARGET. Should you need to narrow your search to a SOURCE or a TARGET, use the -S and -T options.
Already at this point, I was sold on using findmnt instead of mount. I can query the partition that I want. And I don’t use a pipe. Findmnt does not stop there, it has a multitude of options designed to give you a powerful search of the file system.
I think one of the most interesting options is -O, –options. The -O options lets you write a list of options to match your search against. Searching for read-only file system is now as easy as findmnt -O ro.
The -O options can also take a comma-separated list. This let you search against multiple options and list only file system that have all the desired options.
Searching for a given file system type also does not require the use of external tools. Simply use the -t options. In the example below I listed all tmpfs mount.
In all the examples above, findmnt searched /etc/fstab, /etc/mtab and /proc/self/mountinfo. You can easily limit this wide search with the following options:
- –fstab (Narrow search to /etc/fstab only)
- –mtab (Narrow search to /etc/mtab only)
- –kernel (Search in /proc/self/mountinfo only)
Another interesting option is -i, –invert. Which invert the sense of matching. In a previous example, we listed all tmpfs with the -t option. The example below will list all file system of type swap from fstab only.
findmnt --fstab -t swap
This one will list all file systems except any of type swap.
findmnt --fstab -t swap -i
Already with the given options you can avoid using a lot of pipes and external programs. And it does not stop here. Findmnt provides a good set of options to customize the output of your search results.
Customizing the output of findmnt command
You won’t need to use head command to remove the header. Simply call findmnt with -n option:
I was not expecting the next option to even be an option. Findmnt can imitate the output of the df command. Calling findmnt with -D or –df will tell findmnt to display information about space for each listed file system.
Options can be combined for more specific search. In this next example, I use findmnt to list all file system from /etc/fstab and request to display df information.
findmnt --fstab --df
I don’t know about you, but I am starting to enjoy findmnt. Except for those UUID with the last command. I get it, it is a good way to identify device for the OS. Me, I would like a more human readable way. You accomplish this with the -e option.
The -e or –evaluate option with convert all tags like UUID, LABEL, PARTLABEL, PARTUUID to the corresponding device name. See the results when I run the same command with -e options.
I like to way findmnt format it’s output. It is more human friendly. On the other hand, this format when used in a script can be harder to manipulate. A simple line-by-line, space separated data set would be easier. This is easily done with -r, –raw option.
This next option is really nice. I think it remove the need to | grep almost entirely. You can tell findmnt exactly which column to print with the -o, –output. This options take a comma separated list of columns to print. Using the following command you can get just the available space of your root partition with no headers.
findmnt -T / --df -o AVAIL -n
All you have to do in your scripts is to remove the last character. In the above command, I gave the –df option. That was not necessary, same results will be printed even without that option.
Findmnt provides quite an extensive list of output column. I provide you below with a short list of column that I think will be of interest. You can view the full list with findmnt –help
- SOURCE source device
- TARGET mountpoint
- FSTYPE filesystem type
- OPTIONS all mount options
- LABEL filesystem label
- UUID filesystem UUID
- MAJ:MIN major:minor device number
- SIZE filesystem size
- AVAIL filesystem size available
- USED filesystem size used
- USE% filesystem use percentage
- FSROOT filesystem root
The default list of printed column can be extended instead of replaced. Simply provide a list using the following format: +list. The following command will give the same information as using –df, except that the columns will be added to the end.
findmnt -T / -o +SIZE,USE%,AVAIL
Already I am falling in love with findmnt. This will save me lots of piping and long command lines. And findmnt does not stop there. There is one more functionality I want to talk about. Polling.
Yes, findmnt can be used to monitor changes in /proc/self/mountinfo file. This effectively lets you watch your system for mounting related activities. No more while loop in bash scripts.
Findmnt will listen for the following actions, mount, umount, remount and move. You can limit this by providing a comma separated list of actions to listen for. For example, the following will only monitor for mounting file system.
In the above picture, you see the output printed by findmnt when a new partition got mounted. You notice the new column ACTION? With the –poll option you have 3 new column that can be displayed:
- ACTION: Available for mount, umount, remount and move
- OLD-TARGET: Available for umount and move action.
- OLD-OPTIONS: Avalable for umount and remount.
When used in this mode, findmnt will block, if used in a script, the script will “hang”. The time that –poll will block and listen for actions can be limited with 2 options
- –first-only: Findmnt will quit after the first action is detected.
- –timeout X: Findmnt will quit after X milliseconds.
When you put it all together, findmnt is one powerful tool. When used in scripts, you will do away with a lot of extra code. The need to pipe to external command as been greatly diminished.
Previously listed options can also be used with –poll. In the example below, findmnt will listen for a mount action and print the SOURCE,TARGET, SIZE and USE %. But only if the mount target matches the -T options.
findmnt -T /mnt/lfs --poll=mount -o SOURCE,TARGET,SIZE,USE%
Bonus Tip: Real life example of findmnt
I have been working on a bash scripted environment to compile Linux from Scratch for a little while now. Using findmnt in my scripts resulted in better and cleaner code.
During the initial startup of my script, I check to see if LFS partition are mounted, if not the scripts mounts them. The code used to look like this:
if [[ `grep "$pd on $pm" < <(mount) | wc -l` < 1 ]]; then ... ... fi
The project is for education purpose, this is why I used process substitution and pipe in the above test. Throughout my code I display multiple ways to do the same task. Using findmnt I came up with a cleaner way to do the same.
findmnt -S $pd -T $pm > /dev/null || ( ... ... )
I redirect the output to /dev/null, I don’t need to have findmnt output printed on the console. Findmnt will return 1 if the search fails, which will cause the code within ( … ) to execute.
I hope you enjoyed and learned a new command. If you got interesting usage for it, please share in comments. There is also another take on this article: online search are not always the best. We tend to forget that Linux comes with a manual.