Findmnt——在 Linux 上查找已挂载文件系统的更好方法
我一直在研究一个 bash 脚本项目,以便从头开始自动构建 Linux。每次我检查代码时,我都会想办法让它更简洁。我会提取一小部分代码,让它变得更好。
前几天,我做了一个修改,在挂载文件系统之前检查它是否已挂载。我正在寻找一种更好的方法来做到这一点。我不想使用通常的mount | grep或任何类似的代码。我想要一些更干净的东西。
Mount 与 Findmnt
我不知道为什么,但那一刻我发现自己想知道为什么我如此频繁地连接到互联网来查找笔记本电脑上已有的信息。因此,我启动了man mount,我快速浏览了手册页并注意到这一点:
我就找到了答案。首先,我已经用错命令一段时间了。其次,Google 并不总是能给出最佳答案。
讽刺的是,我经常浏览的在线手册页中没有提到这一点。你自己看看吧,在mount的手册页中,findmnt只在最后被引用。如果我通过常规渠道寻找答案,我就不会写这篇文章了。
我立刻就很好奇,这个findmnt有多好?我能从脚本中删除多少个管道?事实证明它比mount listing 好得多。首先,让我们比较一下每个命令的默认输出。
安装默认输出
查看上面列出的已挂载文件系统,很容易明白grep为何如此受欢迎。信息都在那里,但更好的格式会使其更易于阅读。要做到这一点,您已经需要一个管道和外部命令。现在让我们看看findmnt。
Findmnt 默认输出
看起来好多了。情况越来越好,有了findmnt,您就不必再使用多种工具了。它非常灵活,让您有机会在脚本中使用时编写更简洁的代码。
Linux 中 findmnt 命令的实际用法
使用findmnt检查文件系统是否已挂载要容易得多。您可以不使用任何选项来检查源或目标。提供一个挂载点(目标)或设备(源),不带任何选项,findmnt将尝试将您提供的参数与两者进行匹配。
findmnt /boot
Findmnt 的工作原理实际上类似于文件系统的搜索命令。如果找到匹配项,则会打印它们,并且findmnt返回 0。当没有匹配您的查询时,findmnt不会打印任何内容并返回 1。
findmnt带有一长串选项。主要有两类选项:缩小搜索范围和格式化输出。
缩小搜索范围
就像find用于查找文件一样,findmnt用于查找文件系统。您已经知道如何通过提供与 SOURCE 和 TARGET 匹配的字符串来限制搜索。如果您需要将搜索范围缩小到 SOURCE 或 TARGET,请使用 -S 和 -T 选项。
到现在为止,我已经决定使用findmnt而不是mount 了。我可以查询我想要的分区。而且我不用管道。Findmnt 并不止于此,它还有许多选项,旨在为您提供强大的文件系统搜索功能。
我认为最有趣的选项之一是-O、–options。-O选项允许您编写与搜索相匹配的选项列表。搜索只读文件系统现在就像findmnt -O ro 一样简单。
-O选项也可以采用逗号分隔的列表。这样您就可以搜索多个选项并仅列出具有所有所需选项的文件系统。
搜索给定的文件系统类型也不需要使用外部工具。只需使用-t选项即可。在下面的示例中,我列出了所有tmpfs挂载。
在上述所有示例中,findmnt 搜索了 /etc/fstab、/etc/mtab 和 /proc/self/mountinfo。您可以使用以下选项轻松限制此大范围搜索:
- –fstab(将搜索范围缩小至 /etc/fstab)
- –mtab(将搜索范围缩小至 /etc/mtab)
- –kernel(仅在 /proc/self/mountinfo 中搜索)
另一个有趣的选项是-i、–invert。它们反转匹配的意义。在前面的例子中,我们使用-t选项列出了所有tmpfs。下面的示例将仅从 fstab 中列出所有swap类型的文件系统。
findmnt --fstab -t swap
这将列出除交换类型之外的所有文件系统。
findmnt --fstab -t swap -i
使用给定的选项,您可以避免使用大量管道和外部程序。而且它不止于此。Findmnt提供了一组很好的选项来自定义搜索结果的输出。
自定义 findmnt 命令的输出
您不需要使用head 命令来删除标题。只需使用-n选项调用findmnt即可:
我没想到下一个选项竟然是一个选项。Findmnt 可以模仿df 命令的输出。使用-D或–df调用findmnt将告诉findmnt显示每个列出的文件系统的空间信息。
可以组合选项以进行更具体的搜索。在下一个示例中,我使用findmnt从 /etc/fstab 列出所有文件系统并请求显示 df 信息。
findmnt --fstab --df
我不知道你怎么样,但我开始喜欢findmnt 了。除了那些带有最后一条命令的UUID 。我明白了,这是识别操作系统设备的好方法。对我来说,我想要一种更人性化的方式。您可以使用-e选项来实现这一点。
-e或–evaluate选项会将所有标签(如 UUID、LABEL、PARTLABEL、PARTUUID)转换为相应的设备名称。当我使用-e选项运行相同命令时,请查看结果。
我喜欢findmnt格式的输出。它更人性化。另一方面,这种格式在脚本中使用时可能更难操作。简单的逐行、空格分隔的数据集会更容易。这很容易用-r、–raw选项完成。
下一个选项非常好。我认为它几乎完全消除了对| grep的需要。您可以使用-o , –output告诉findmnt确切要打印哪一列。此选项以逗号分隔的要打印的列列表。使用以下命令,您可以仅获取没有标题的根分区的可用空间。
findmnt -T / --df -o AVAIL -n
您在脚本中要做的就是删除最后一个字符。在上面的命令中,我给出了–df选项。这不是必需的,即使没有该选项也会打印相同的结果。
Findmnt 提供了相当广泛的输出列列表。下面我为您提供了一个我认为您会感兴趣的简短的列列表。您可以使用findmnt –help查看完整列表
- SOURCE 源设备
- 目标挂载点
- FSTYPE 文件系统类型
- OPTIONS 所有挂载选项
- LABEL 文件系统标签
- UUID 文件系统 UUID
- MAJ:MIN 主:次设备号
- SIZE 文件系统大小
- AVAIL 可用的文件系统大小
- USED 使用的文件系统大小
- USE% 文件系统使用百分比
- FSROOT 文件系统根
可以扩展默认的打印列列表,而不必替换。只需使用以下格式提供列表:+list。以下命令将提供与使用–df相同的信息,只是列将添加到末尾。
findmnt -T / -o +SIZE,USE%,AVAIL
我已经爱上了findmnt。这将为我节省大量管道和长命令行。而且findmnt还不止于此。我还想谈谈另一个功能。轮询。
是的,findmnt可用于监视 /proc/self/mountinfo 文件中的更改。这可让您有效地监视系统中的挂载相关活动。bash脚本中不再有 while 循环。
Findmnt将监听以下操作:mount、umount、remount和move。您可以通过提供逗号分隔的要监听的操作列表来限制此操作。例如,以下内容将仅监视正在挂载的文件系统。
在上图中,您可以看到挂载新分区时findmnt打印的输出。您注意到了新的ACTION列吗?使用–poll选项,您可以显示 3 个新列:
- 动作:可用于挂载、卸载、重新挂载和移动
- OLD-TARGET:可用于卸载和移动操作。
- 旧选项:可用于卸载和重新安装。
在此模式下使用时,findmnt将阻塞,如果在脚本中使用,脚本将“挂起”。可以使用 2 个选项限制–poll阻塞和监听操作的时间
- –first-only:检测到第一个动作后,Findmnt 将会退出。
- –timeout X:Findmnt 将在 X 毫秒后退出。
当你把所有这些组合起来时,findmnt就是一款功能强大的工具。在脚本中使用时,你将省去大量额外的代码。通过管道传输到外部命令的需要已大大减少。
前面列出的选项也可以与–poll一起使用。在下面的示例中,findmnt将监听挂载操作并打印 SOURCE、TARGET、SIZE 和 USE%。但前提是挂载目标与-T选项匹配。
findmnt -T /mnt/lfs --poll=mount -o SOURCE,TARGET,SIZE,USE%
附加提示:findmnt 的真实示例
我一直在开发一个 bash 脚本环境,以便从 Scratch 编译 Linux。在我的脚本中使用findmnt可以生成更好、更干净的代码。
在我的脚本首次启动时,我会检查 LFS 分区是否已挂载,如果没有,脚本就会挂载它们。代码以前看起来像这样:
if [[ `grep "$pd on $pm" < <(mount) | wc -l` < 1 ]];
then
...
...
fi
该项目用于教育目的,这就是我在上述测试中使用进程替换和管道的原因。在我的代码中,我展示了多种完成相同任务的方法。使用findmnt,我想到了一种更简洁的方法来做同样的事情。
findmnt -S $pd -T $pm > /dev/null || (
...
...
)
我将输出重定向到 /dev/null,我不需要将findmnt输出打印在控制台上。如果搜索失败, Findmnt将返回 1,这将导致 (...) 内的代码执行。
希望您喜欢并学会了新命令。如果您发现有趣的用法,请在评论中分享。这篇文章还有另一种看法:在线搜索并不总是最好的。我们往往会忘记 Linux 附带手册。