如何识别哪些目录位于不同的文件系统上?

如何识别哪些目录位于不同的文件系统上?

想象一下,我位于一个目录(例如,/mnt)中,其中一些目录是另一个文件系统的挂载点,而其他目录是同一文件系统上的合法目录。我可以发出一个简单的命令来列出当前目录的内容,以便我区分这两种目录吗?

一种可能性是tree -L 1 -x,它只会扩展同一文件系统上的那些文件夹,但是如果所有这些文件夹都是空的(即,空文件系统安装到安装点,并且合法目录是空目录),则这不起作用)。

(我在这里的真正用例是 btrfs 文件系统,能够轻松识别哪些目录是子卷,哪些不是。)

编辑:我收到朋友的建议,使用它df来获取每个文件的挂载点,因此可以通过运行以下命令列出不同文件系统上的所有文件夹:

comm -1 -3 \
  <(df --output=target . | sort) \
  <(df --output=target * | sort | uniq) |
  xargs basename -a

该命令在所有文件上运行以获取其挂载点,并删除当前目录中df的输出(这也会删除标头),然后检索每个文件的基本名称。df然而,这并不是特别优雅并且很脆弱(至少是因为换行符,也许是因为我忽略了一些事情)。有没有更好的办法?

答案1

我会用df这个。

$ cd /usr

$ ls
X11R6       include     libexec     mdec        sbin        xobj
bin         lib         local       obj         share       xsrc
games       libdata     lost+found  ports       src

$ for d in *; do test -d "$d" && df -P "$d" | awk -v d="$d" 'FNR>1{print d,$NF}'; done 
X11R6 /usr
bin /usr
games /usr
include /usr
lib /usr
libdata /usr
libexec /usr
local /usr/local
lost+found /usr
mdec /usr
obj /usr
ports /usr/ports
sbin /usr
share /usr
src /usr
xobj /usr
xsrc /usr

答案2

统计数据(如果 * 扩展为非常大的东西,可能会溢出 ARG_MAX):

stat -c '%D %n' */ | awk -v no=$(stat -c %D /) ' $1 != no { print $2 }'

寻找:

find . -mindepth 1 -maxdepth 1 -type d -printf '%D\t%P\n'  |grep -v "^$(stat -c%d /)" |cut -f2

答案3

在 Linux 上,您可以使用stat列出与每个已安装文件系统关联的唯一标识符:

stat -f -c %i somefile

例如,要列出当前目录下的挂载点(假设文件名中没有换行符),您可以运行

stat -f -c '%i %n' * | grep -v "^$(stat -f -c %i .)"

在 zsh 中,您可以使用zsh/stat模块。加载它zmodload zsh/stat,然后

zstat +device *

列出当前目录中的挂载点:

zstat +device * | grep -v " $(zstat +device .)"

或者

print -rl -- *(e\''[[ $(zstat +device $REPLY) == '$(zstat +device .)' ]]'\')

请注意,对于同一文件系统的不同视图,文件系统标识符是相同的,例如,如果您在不同位置挂载相同的网络共享,或者使用 Linux 绑定挂载。然而 btrfs 子卷确实有自己的标识符。解析输出df更加繁琐,但没有这个限制。

相关内容