首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从findmnt结果列表中排除绑定挂载?

如何从findmnt结果列表中排除绑定挂载?
EN

Unix & Linux用户
提问于 2018-03-14 00:32:51
回答 1查看 1.2K关注 0票数 3

在bash脚本中,我有以下几行:

代码语言:javascript
复制
TARGETS="$(findmnt -n -v -t btrfs -o TARGET --list)"
UUIDS="$(findmnt -n -v -t btrfs -o UUID --list)"

我在一些服务器上运行这个脚本(运行Arch )。但是,它在NFS服务器上失败。在这种情况下,findmnt返回给定UUID的multiple挂载点(因为绑定安装在NFS服务器上)。我的脚本的一个要求是,我为每个UUID提供了一个one挂载点列表。

我在这里找到了一个非常好的答案(只显示“有趣的”挂载点/过滤非感兴趣的类型),并尝试了这里讨论的所有建议,我仍然无法消除findmnt返回给定UUID的多个挂载点--即使问题被缩小到仅由绑定挂载引起的重复。(我错过了什么吗?)

作为临时解决办法,我所做的是创建一个有限的选项卡文件,其中只包含我想要显示的挂载,然后我在findmnt中使用-F选项。我的自定义选项卡文件是fstab的副本,所有绑定挂载都已删除。

代码语言:javascript
复制
TARGETS="$(findmnt -n -v -t btrfs -o TARGET --list -F /etc/fstab.custom)"
UUIDS="$(findmnt -n -v -t btrfs -o UUID --list -F /etc/fstab.custom)"

显然,这是一种脆弱的方法,一旦/etc/fstab中发生任何更改,并且我的自定义选项卡文件没有手动更新,它就会中断。(我还不得不手动删除一些导致自定义文件中重复的非绑定挂载,因此在这个阶段它肯定不是一个健壮的解决方案。)

有什么更好的方法来达到预期的结果?我可以想象这个问题可以用findmnt过滤器解决,也可以通过应用到findmnt返回的列表的外部过滤器来解决。

我所有的绑定挂载都以"/srv/nfs/“开头。从列表中筛选出这些将是一个好的开始,尽管我认为这也是一个有点脆弱的解决方案(因为有一天有人可能会决定改变NFS绑定挂载在服务器上的组织方式)。

另外,我在bash或awk方面还不够好,不知道如何对findmnt返回的结果进行后处理。我想过这个:

代码语言:javascript
复制
findmnt -n -t btrfs -o UUID,TARGET --list | grep -v -E "/srv/nfs|.tapp|/var/log"

但是,这似乎和自定义选项卡文件一样脆弱,因为对路径名的任何更改都会破坏它。

下面是findmnt -n -t btrfs -o UUID,TARGET --list在我的一个系统上返回的一个示例(安装点简化了):

代码语言:javascript
复制
473c1g34-23ec-41dd-671f-c71473ad7d36 /
473c1g34-23ec-41dd-671f-c71473ad7d36 /srv/nfs/foo/wunder
473c1g34-23ec-41dd-671f-c71473ad7d36 /srv/nfs/foo/tinder
473c1g34-23ec-41dd-671f-c71473ad7d36 /.tapp
473c1g34-23ec-41dd-671f-c71473ad7d36 /var/log
473c1g34-23ec-41dd-671f-c71473ad7d36 /var/log/.tapp
13f4361e-771e-44b3-7413-a613bf4e331b /bar
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user1/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user6/Desktop
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user3/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user4/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user5/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user6/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /bar/.tapp
3ac663cc-e7e4-4764-7a7a-1d3fa16b376b /foo/files
3ac663cc-e7e4-4764-7a7a-1d3fa16b376b /srv/nfs/foo/files
4c61646e-1a1d-4d67-7d47-1446e41d6341 /bar/baz
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/goop/stuff
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/goop/widgets
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/pie
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/goop/gadgets
4c61646e-1a1d-4d67-7d47-1446e41d6341 /bar/baz/.tapp

我需要过滤掉所有nfs绑定挂载(那些以/srv/nfs开头的挂载)和包含/.tapp的所有挂载点以及/var/log的挂载点。有没有办法用findmnt选项来做到这一点?如果没有,怎么在bash做呢?

<#>UPDATE:为了保持问题的焦点,我希望有一种方法将绑定挂载排除在findmnt结果列表之外。为了提供答案,请忽略其他重复的挂载点,如/var/log所创建的。

UPDATE 2:下面是一个json格式的findmnt输出示例。我看不出有什么方法可以区分绑定挂载和我希望保留的输出中的绑定挂载(/foo/file)。

代码语言:javascript
复制
{"target": "/srv/nfs/bar/user1/Documents", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/srv/nfs/home/user5/Desktop", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/srv/nfs/home/user3/Documents", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/srv/nfs/home/user4/Documents", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/foo/files", "uuid": "3ac663cc-e7e4-4764-7a7a-1d3fa16b376b"},
EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2018-03-14 00:45:43

仅列出绑定挂载相比,绑定挂载似乎无法与挂载后的原始挂载区分开来。虽然部分绑定(其中一个挂载点的子目录在某个地方挂载)在findmnt输出中显示的方式不同,但是没有区别的挂载点是在其他地方挂载的。

所以如果我这么做了

代码语言:javascript
复制
sudo mount -o bind / /srv
sudo mount -o bind /media /mnt

在挂载信息方面,我无法区分//srv,但我可能能够区分/media/mnt

因此,剩下的只是从findmnt中删除重复的条目:

代码语言:javascript
复制
findmnt -n -t btrfs -o UUID,TARGET -r | awk '!a[$1]++'

使用-r选项而不是-l,它将转义输出中的特殊字符,这样您就可以安全地处理路径:

代码语言:javascript
复制
$ findmnt -n -t ext4 -o UUID,TARGET -r
d4873b63-0956-42a7-9dcf-bd64e495a9ff /
..
d4873b63-0956-42a7-9dcf-bd64e495a9ff /srv/media
d4873b63-0956-42a7-9dcf-bd64e495a9ff /a\x20b
d4873b63-0956-42a7-9dcf-bd64e495a9ff /srv/a\x20b

在这里,a b被转义为a\x20b。可以在bash中使用printf "%b"展开转义字符:

代码语言:javascript
复制
$ findmnt -n -t ext4 -o UUID,TARGET -r | bash -c 'while read -r uuid point; do printf "%b\n" "$point"; done'
/
...
/srv/media
/srv/a b
/a b
/srv/a b
票数 2
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/430074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档