想象一下,我位于一个目录(例如,/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
更加繁琐,但没有这个限制。