有没有办法在 Linux 上递归地搜索树中的挂载点?我想做这样的事情:
find /tree -type mountpoint | sort -r | xargs umount
答案1
如果你有一个mountpoint
命令并且它支持-q
,你可以这样做:
find /tree -depth ! -type l -exec mountpoint -q {} \; -print
但这意味着mountpoint
每个非符号链接文件运行一个命令。
请注意,当文件系统屏蔽挂载点时,至少 Linuxmountpoint
可能会出错。例如,如果一个文件系统安装在 上/a/b
,但稍后安装了另一个文件系统/a
并且也恰好包含一个b
目录,mountpoint
则将声称/a/b
是一个安装点,即使它不是。 (但这在现实生活中很少发生)。
您可能最好将每个路径与/proc/mounts
(如果在 Linux 上)或mount
.
喜欢:
eval "$(
< /proc/mounts perl -MString::ShellQuote -lane '
BEGIN{@trees = @ARGV; undef @ARGV}
$_ = $F[1]; # mountpoint is on the 2nd field
s/\\(...)/chr oct $1/ge; # unescape \ooo sequences
s/[[\\?*]/\\$&/gs; # escape wildcards
push @mountpoints, $_;
END {
# output the find command to evaluate:
print shell_quote(
"find", @trees, qw{-depth ! -type l ( -path},
shift @mountpoints,
(map {("-o", "-path", $_)} @mountpoints),
")", "-print")
}' /tree /other/tree
)"
(/tree
并且必须是绝对路径和无符号链接。这会遇到与上面提到的/other/tree
相同的问题)。mountpoint
如果您只想卸载 下的文件系统/tree
,请注意 中的条目/proc/mounts
按其安装顺序显示,因此要卸载它们,只需反向处理该文件即可:
例如卸载下面的所有 FS /tree
:
< /proc/mounts perl -l0 -ane '
$_ = $F[1];
s/\\(...)/chr oct $1/ge; # unescape \ooo sequences
unshift @mountpoints, $_ if "$_/" =~ m{^/tree/};
END {print for @mountpoints}' | xargs -r0 umount
如果您知道挂载点不包含换行符,您还可以执行以下操作:
findmnt -rnRo target /tree | tac | xargs -rd '\n' umount
或者更详细/清晰:
findmnt --raw --noheadings --submounts --output=target /tree |
tac | xargs --no-run-if-empty --delimiter='\n' umount
答案2
这不是特别优雅,但应该可行。只需忽略错误并继续尝试,直到卸载所有内容:
while mount | grep -q /tree; do
mount | awk '/tree/{print $3}' | xargs sudo umount 2>/dev/null
done
上面假设您是一个理智的人,不会在安装点中使用空格或其他奇怪的字符。如果情况并非如此,请改用此选项(此选项假定您没有名称同时包含on
和的安装点type
):
while mount | grep -q /tree; do
mount | sed -nE 's/.*\s+on\s+(.*baba.*)\s+type.*/\1/p' |
xargs sudo umount 2>/dev/null
done
答案3
尝试这个 ...
find /tree -depth -type d -inum 2 -print | xargs umount
抱歉,我无法测试这个...但理论上是每个文件系统的根目录都有索引节点号 2(至少对于 ext[2-4] 和大多数其他类 UNIX 文件系统...来确认这一点/
run ls -ldi /
- inode 编号将是左列中的编号)。
答案4
您可以使用“mountpoint”命令来实现此目的。例如:
find /tree -exec sh -c "mountpoint {} 2>/dev/null" \; | grep "is a mountpoint" | awk '{print $1}'|sort -r | xargs umount {}