我想确定文件或目录位于哪个子卷上。例如,如果我有一个子卷挂载点/mnt/btrfs-subvol
和一个目录/mnt/btrfs-subvol/some/dir
,并且我运行something /mnt/btrfs-subvol/some/dir
它会返回btrfs-subvol
.
我能想到的最好办法就是返回,用stat
256 的索引节点测试每个目录,但我无法想象这是唯一的方法。或者也许可以跑
until btrfs sub show `pwd`; cd ..;done; echo `pwd`
但我觉得应该有一个更优雅的解决方案。
答案1
如果你可以使用stat
(POSIX 不需要)并且它的选项足够丰富,那么这个命令:
stat --format=%m /mnt/btrfs-subvol/some/dir
会告诉你你想要什么。注释dir
可以是任何类型文件,不一定是目录。
笔记:
手册上说
%m
表示挂载点;对于 Btrfs,这有些误导。我在 Kubuntu 18.04.5 LTS 中的测试表明,即使/mnt/btrfs-subvol/
不是显式挂载点(即mount whatever /mnt/btrfs-subvol/
从未发生过),但它是一个子卷(在显式挂载为/
或 的子卷内/mnt/
),那么该命令会将其视为挂载点。看来这就是你想要的。输出是操作系统中目录结构中有效的路径,而不是设备上 Btrfs 目录(和子卷)树中的有效路径(如果您不确定有什么区别,请阅读这个问题以及我的答案)。再次看来这种行为正是您想要的。
该命令对 Btrfs 以外的文件系统有效(例如在我的 Kubuntu 中
stat --format=%m /dev/null
打印/dev
)。显然,一般其他文件系统没有子卷的概念。也许您应该首先检查您要查找的文件是否位于 Btrfs 文件系统中:stat --file-system --format=%T /mnt/btrfs-subvol/some/dir
如果您看到,
btrfs
则继续执行主命令来查找子卷。不幸的是,一次调用stat
无法打印两条信息(无论有--file-system
或没有)。上面的结论意味着你需要运行
stat
两次。无法保证他们会dir
在路径下看到相同的内容/mnt/btrfs-subvol/some/dir
。如果中间发生一些(卸载)安装怎么办?比较托克图。在 Linux 中,我可以stat
通过使用文件描述符在同一个文件上可靠地运行两个 s,而无需 TOCTOU:( stat --dereference --file-system --format=%T /proc/self/fd/3 stat --dereference --format=%m /proc/self/fd/3 ) 3</mnt/btrfs-subvol/some/dir
注意,如果
dir
它本身是一个符号链接,命令将遵循它。您仍然可能想知道子卷以便稍后对其进行处理。无论如何,你都会把它当作一条路径。在你使用它之前,情况可能会发生变化,TOCTOU可能会打击你。
如果您非常确定相关路径在未经您同意的情况下不会改变其含义,那么只需
stat
以简单的方式处理 s 及其结果即可。在我的测试中,
stat --file-system …
行为就像stat --file-system --dereference …
.这意味着如果目标文件是符号链接,则stat
带有和不带--file-system
(均不带显式)的 s 可能会产生不一致的结果。--dereference