检查目录是不是用 bash 挂载

Posted

技术标签:

【中文标题】检查目录是不是用 bash 挂载【英文标题】:Check if directory mounted with bash检查目录是否用 bash 挂载 【发布时间】:2012-03-14 09:55:59 【问题描述】:

我正在使用

mount -o bind /some/directory/here /foo/bar

我想用 bash 脚本检查/foo/bar,看看它是否已挂载?如果不是,则调用上面的 mount 命令,否则执行其他操作。我该怎么做?

CentOS 是操作系统。

【问题讨论】:

类似“如果 [[ $(mount -l ... | fgrep ... | wc -l) ]]; 然后 ...” Server Fault、Stack Overflow 和 Unix & Linux Stack Exchange 上有类似问题。 【参考方案1】:

这里的答案太复杂了,只需检查安装是否存在:

cat /proc/mounts | tail -n 1

这只会输出最后一个挂载的文件夹,如果你想查看所有文件夹,只需删除 tail 命令即可。

【讨论】:

【参考方案2】:

我喜欢使用/proc/mounts 的答案,但我不喜欢做简单的grep。这会给你带来误报。您真正想知道的是“是否有任何行具有字段编号 2 的确切字符串”。所以,问这个问题。 (在这种情况下,我正在检查/opt

awk -v status=1 '$2 == "/opt" status=0 END exit status' /proc/mounts

# and you can use it in and if like so:

if awk -v status=1 '$2 == "/opt" status=0 END exit status' /proc/mounts; then
  echo "yes"
else
  echo "no"
fi

【讨论】:

这太可爱了!正是您想要的小型嵌入式系统,其中不存在像 mountpointfindmnt 这样的华丽工具。很简单的回复,很开心,这样的UNIX :)【参考方案3】:

我的解决方案:

is_mount() 
    path=$(readlink -f $1)
    grep -q "$path" /proc/mounts

例子:

is_mount /path/to/var/run/mydir/ || mount --bind /var/run/mydir/ /path/to/var/run/mydir/

对于Mark J. Bobak's answer,如果在不同的文件系统中使用bind 选项挂载,mountpoint 将不起作用。

对于Christopher Neylan's answer,不需要将grep的输出重定向到/dev/null,直接使用grep -q即可。

最重要的,使用readlink -f $mypath规范化路径

如果检查路径如/path/to/dir/以反斜杠结尾,则/proc/mountsmount输出中的路径为/path/to/dir 在大多数 linux 版本中,/var/run//run/ 的符号链接,因此如果您为/var/run/mypath 挂载绑定并检查它是否挂载,它将在/proc/mounts 中显示为/run/mypath

【讨论】:

我认为 "grep -q "$path " /proc/mounts" (带空格)更好...否则如果安装了 abc,is_mount ab 将返回 true?!【参考方案4】:

mountpoint的手册说:

检查给定的目录或文件是否在 /proc/self/mountinfo 文件中被提及。

mount 的手册说:

维护列表模式仅是为了向后兼容。为了 更健壮和可定制的输出使用 findmnt(8),尤其是在你的 脚本。

所以正确使用的命令是findmnt,它本身就是util-linux 包的一部分,根据手册:

能够在 /etc/fstab、/etc/mtab 或 /proc/self/mountinfo 中搜索

所以它实际上搜索的东西比mountpoint 更多。它还提供了方便的选项:

-M, --mountpoint 路径

明确定义挂载点文件或目录。另见--target。

总而言之,要检查一个目录是否用 bash 挂载,可以使用:

if [[ $(findmnt -M "$FOLDER") ]]; then
    echo "Mounted"
else
    echo "Not mounted"
fi

例子:

mkdir -p /tmp/foo/a,b
cd /tmp/foo

sudo mount -o bind a b
touch a/file
ls b/ # should show file
rm -f b/file
ls a/ # should show nothing

[[ $(findmnt -M b) ]] && echo "Mounted"
sudo umount b
[[ $(findmnt -M b) ]] || echo "Unmounted"

【讨论】:

【参考方案5】:

在我的 .bashrc 中,我做了以下别名:

alias disk-list="sudo fdisk -l"

【讨论】:

请求是关于脚本的,最好避免sudo和目标是“操作磁盘分区”的程序【参考方案6】:

另一个干净的解决方案是这样的:

$ mount | grep /dev/sdb1 > /dev/null && echo mounted || echo unmounted

当然,'echo something' 可以替换为您需要针对每种情况执行的任何操作。

【讨论】:

这与@ChristopherNeylan 的回答完全相同。【参考方案7】:

运行不带参数的mount 命令将告诉您当前的挂载。在 shell 脚本中,您可以使用 grep 和 if 语句检查挂载点:

if mount | grep /mnt/md0 > /dev/null; then
    echo "yay"
else
    echo "nay"
fi

在我的示例中,if 语句正在检查 grep 的退出代码,这表明是否存在匹配项。由于我不希望在匹配时显示输出,因此我将其重定向到/dev/null

【讨论】:

你不需要检查它是否返回一个字符串。 grep 如果没有匹配项,则返回非零退出状态。不需要测试,也不需要 $() 创建的子shell。 if command | grep -q 'stuff'; then ... 这不适用于安装绑定,因此不应被接受为答案。这个答案应该被否决。您不能依赖mount | grep ... 向您显示您的挂载绑定仍然处于活动状态。如果底层设备被卸载并重新安装,即使mount 仍然显示它已连接,安装绑定实际上将不再连接两个文件/目录。如果你这样做umount ... 它甚至会告诉你它没有安装,尽管mount 说它是。 linux文件系统中的巨大缺陷。 @DevNull:我遇到的正是您所描述的问题。这个问题有什么解决办法吗? @Isaac,抱歉延迟回复。我会尝试使用readlink -f,当路径/文件不存在时它不会返回任何内容。如果底层 /mount/path/to_file 不存在(每个读取链接),则底层挂载被破坏(重新挂载底层挂载和绑定)。如果底层文件存在并且readlink -f 说该文件的绑定版本不存在,则绑定已损坏,只需重新挂载绑定即可。 如果有一个名为/mnt/md0xxx 的挂载,那么该命令将指示/mnt/md0 已挂载,而它不必是...【参考方案8】:

您没有费心提及操作系统。

Ubuntu Linux 11.10(可能是最新版本的 Linux)具有 mountpoint 命令。

这是我的一台服务器上的示例:

$ mountpoint /oracle
/oracle is a mountpoint
$ mountpoint /bin
/bin is not a mountpoint

实际上,在您的情况下,您应该可以使用-q 选项,如下所示:

mountpoint -q /foo/bar || mount -o bind /some/directory/here /foo/bar

希望对您有所帮助。

【讨论】:

您在运行“mountpoint”命令时实际上已经安装了一些东西?即使它打算成为一个挂载点,除非它实际上挂载了一些东西,否则它只是一个目录。 +1,同样适用于 Ubuntu 10.10。 It's been in Ubuntu since 8.04. 安装点也存在于 RHEL 6.3 中(甚至可能在早期版本中) mountpoint 存在并且可以在 Debian 7 ("Wheezy") 和 UCS 4 上完美运行 如another comment 中所述,挂载点不适用于绑定挂载。 sn -p 会多次挂载目录

以上是关于检查目录是不是用 bash 挂载的主要内容,如果未能解决你的问题,请参考以下文章

检查 NFS 目录是不是在失败时挂载而没有大挂起

bash 命令检查目录是不是可执行

Bash:检查目录是不是仅包含具有特定后缀的文件

检查传递的参数是不是是 Bash 中的文件或目录

Docker挂载本地目录

Docker挂载本地目录