it-swarm.cn

检查Bash脚本中是否挂载了卷的最佳方法是什么?

检查Bash脚本中是否挂载了卷的最佳方法是什么?

我真正想要的是一种可以像这样使用的方法:

if <something is mounted at /mnt/foo> 
then
   <Do some stuff>
else
   <Do some different stuff>
fi
109
Mark Biek

避免使用/etc/mtab,因为它可能不一致。

避免使用mount,因为它不必那么复杂。

只是:

if grep -qs '/mnt/foo ' /proc/mounts; then
    echo "It's mounted."
else
    echo "It's not mounted."
fi

/mnt/foo后面的空格是为了避免例如/mnt/foo-bar的匹配。)

122
Dan Carley
if mountpoint -q /mnt/foo 
then
   echo "mounted"
else
   echo "not mounted"
fi

要么

mountpoint -q /mnt/foo && echo "mounted" || echo "not mounted"
61
Zaptac

findmnt -rno SOURCE,TARGET "$1"避免了其他答案中的所有问题。它只用一个命令就可以完成这项工作。


其他方法也有这些缺点:

  • grep -qgrep -s是多余的步骤,并非所有地方都支持。
  • /proc/\*并非在所有地方都受支持。
  • mountinfo基于/ proc /。
  • cut -f3 -d' '弄乱路径名中的空格
  • 解析mount的空格是有问题的。它的手册页现在说:

..列表模式仅用于向后兼容。

对于更健壮和可定制的输出,请使用findmnt(8),尤其是在脚本中。


bash函数:

#These functions return exit codes: 0 = found, 1 = not found

isMounted    () { findmnt -rno SOURCE,TARGET "$1" >/dev/null;} #path or device
isDevMounted () { findmnt -rno SOURCE        "$1" >/dev/null;} #device only
isPathMounted() { findmnt -rno        TARGET "$1" >/dev/null;} #path   only

#where: -r = --raw, -n = --noheadings, -o = --output

用法示例:

if isPathMounted "/mnt/foo bar";      #Spaces in path names are ok.
   then echo "path is mounted"
   else echo "path is not mounted"
fi

if isDevMounted "/dev/sdb4"; 
   then echo "device is mounted"
   else echo "device is not mounted"
fi

#Universal:
if isMounted "/mnt/foo bar"; 
   then echo "device is mounted"
   else echo "device is not mounted"
fi

if isMounted "/dev/sdb4";
   then echo "device is mounted"
   else echo "device is not mounted"
fi
21
Elliptical view

像这样的脚本永远不会移植。 unix中一个肮脏的秘密是,只有内核知道什么文件系统在哪里,而缺少/ proc(不可移植)之类的东西,它永远不会给您一个直接的答案。

我通常使用df来发现子目录的安装点及其所在的文件系统。

例如(需要posix Shell,如ash/AT&T ksh/bash等)

case $(df  $mount)
in
  $(df  /)) echo $mount is not mounted ;;
  *) echo $mount has a non-root filesystem mounted on it ;;
esac

Kinda会告诉您有用的信息。

7
chris

以下是我在我的rsync备份cron作业之一中使用的内容。它会检查是否已安装/ backup,并尝试未安装/ backup(它可能会失败,因为驱动器位于热插拔托架中,甚至可能不存在于系统中)

注意:以下内容仅适用于linux,因为它会干扰/ proc/mounts-更具移植性的版本将运行'mount | grep/backup”,如Matthew的回答。

如果! grep -q/backup/proc/mounts;然后
如果!挂载/备份;然后
回显“失败” 
退出1 
 fi 
 fi 
回显“成功。” 
#在这里做一些事情
6
cas

由于要进行挂载,无论如何都需要在该目录中挂载一个目录,因此我的策略始终是使用伪造的文件名创建一个永远不会使用的伪造文件,并检查其是否存在。如果文件在那里,那么那个地方什么都不会挂载...

我认为这不适用于安装网络驱动器或类似的东西。我将其用于闪存驱动器。

2
Brian Postow

如何比较设备编号?我只是想想最深奥的方法。

#!/bin/bash
if [[ $(stat -c "%d" /mnt) -ne $(stat -c "%d" /mnt/foo) ]]; then
    echo "Somethin mounted there I reckon"
fi

我的逻辑上有一个缺陷...

作为功​​能:

#!/usr/bin/bash
function somethingMounted {
        mountpoint="$1"
        if ! device1=$(stat -c "%d" $mountpoint); then
                echo "Error on stat of mount point, maybe file doesn't exist?" 1>&2
                return 1
        fi
        if ! device2=$(stat -c "%d" $mountpoint/..); then
                echo "Error on stat one level up from mount point, maybe file doesn't exist?" 1>&2
                return 1
        fi

        if [[ $device1 -ne $device2 ]]; then
                #echo "Somethin mounted there I reckon"
                return 0
        else
                #echo "Nothin mounted it seems"
                return 1
        fi
}

if somethingMounted /tmp; then
        echo "Yup"
fi

回显错误消息可能是多余的,因为stat也将显示错误。

2
Kyle Brandt

很抱歉提出这个问题,但我认为这非常有用:

if awk '{print $2}' /proc/mounts | grep -qs "^/backup$"; then
    echo "It's mounted."
else
    echo "It's not mounted."
fi

这将获得/ proc/mounts的第二列(第二列=安装点)。

然后,它抓住输出。注意^和$,这可以防止/ backup与/ mnt/backup或/ backup-old等匹配。

1
David

这些都不满足用例,其中给定目录是另一个安装点内的子目录。例如,您可能拥有/ thing,它是NFS挂载到Host:/ real_thing的位置。为此,不能在/ proc/mounts/etc/mtab或'mount'上使用grep,因为您将查找不存在的挂载点。例如,/ thing/thingy不是挂载点,但是/ thing挂载在Host:/ real_thing上。实际上,这里投票的最佳答案不是“确定目录/卷是否已安装的最佳方法”。我赞成使用'df -P'(-P POSIX标准模式)作为更清洁的策略:

dev=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $1 ; exit } END { exit e }'` && {
    echo "Mounted via: $dev"
} || {
    echo "Not mounted"
}

运行此命令的输出将是:

Mounted via: Host:/real_thing

如果您想知道真正的挂载点是什么,那么没问题:

mp=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $NF ; exit } END { exit e }'` && {
    echo "Mounted on: $mp"
} || {
    echo "Not mounted"
}

该命令的输出将是:

Mounted on: /thing

如果您尝试创建某种类型的chroot,以通过任意目录或文件列表在chroot中的chroot外部镜像安装点,那么这将非常有用。

1
Craig

取决于您对要检查的卷的了解。

在我最近研究的特定案例中,我担心要查找是否安装了特定的闪存驱动器,最容易起作用的是检查/ dev/disks/by-label /的存在。如果已插入设备,则udev脚本将确保链接存在(并且在拔出设备时将其删除)。

(这不是一个高度可移植的答案;不过,它可以在许多现代Linux发行版中使用,并且该问题针对Linux进行了标记,与迄今为止提到的任何方法完全不同,因此扩展了可能性。)

0
David Dyer-Bennet

我喜欢使用/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
0
Bruno Bronosky

尽管这是一个Linux问题,但为什么在轻松完成后不使其具有可移植性呢?

grep的手册页显示:

可移植Shell脚本应避免同时使用-q和-s,并且应将标准和错误输出重定向到/dev/null代替。

因此,我提出以下解决方案:

if grep /mnt/foo /proc/mounts > /dev/null 2>&1; then
        echo "Mounted"
else
        echo "NOT mounted"
fi
0
fex

grep/etc/mtab可能是您的挂载点?

0
Ophidian

是否需要比这更复杂?

mount \
    | cut -f 3 -d ' ' \
    | grep -q /mnt/foo \
  && echo "mounted" || echo "not mounted"
0
Matthew Bloch

这个?:

volume="/media/storage"
if mount|grep $volume; then
echo "mounted"
else
echo "not mounted"
if

来自: 一个Ubuntu论坛

0
RateControl

在安装点下创建文件,例如check_mount,然后测试是否存在?

if [[ -f /something/check_mount ]]; then
   echo "Mounted
   RC=$?
else
   Echo "Not mounted"
   RC=0
fi
exit $RC
0
Wiljami