检查卷是否安装在 Bash 脚本中的最佳方法是什么?

Mar*_*iek 139 linux bash mount

检查卷是否安装在 Bash 脚本中的最佳方法是什么?

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

if <something is mounted at /mnt/foo> 
then
   <Do some stuff>
else
   <Do some different stuff>
fi
Run Code Online (Sandbox Code Playgroud)

Dan*_*ley 162

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

避免管道,mount因为它不需要那么复杂。

简单地:

if grep -qs '/mnt/foo ' /proc/mounts; then
    echo "It's mounted."
else
    echo "It's not mounted."
fi
Run Code Online (Sandbox Code Playgroud)

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

  • 实际上,您应该测试 '/mnt/foo ',即。有一个空格,否则如果您安装了一个名为 eg. 的卷,您可能会得到误报。'傻瓜'。我刚刚遇到了两个挂载点“lmde”和“lmde-home”的问题。 (24认同)
  • 更不用说,如果挂载点被楔入,对 mount 的调用可能会挂起。 (11认同)
  • 适用于 linux,不适用于 freebsd 或 solaris。 (9认同)
  • 这是真的,克里斯。虽然这个问题被标记为 linux。 (5认同)
  • 我想这是一个哲学问题——如果可能的话,我们应该尝试使事情变得可移植,还是应该假设全世界都在运行 Windows/Linux 并采取相应的行动? (3认同)
  • 可能值得一提的是:如果您在比 shell 脚本更低的级别使用 /proc/mounts(例如,使用 Perl 或 Python 进行解析),您必须记住 [`/proc/mounts` 在对 `read 的单个调用中只是原子的()`](http://stackoverflow.com/a/5880485/265575)——所以一定要读取整个文件然后解析它,而不是依赖于从文件句柄本身逐行解析。 (3认同)
  • 或者跳过 if/else 并使用:`grep -qs '/mnt/foo' /proc/mounts &amp;&amp; echo "It's installed." || 回声“它没有安装”。` (2认同)
  • 回复:linux vs 非 linux,这个问题被标记为 linux。所以假设Linux是可以的。否则,它就像为 linux 问题提供 Windows 答案一样有意义。 (2认同)

小智 88

if mountpoint -q /mnt/foo 
then
   echo "mounted"
else
   echo "not mounted"
fi
Run Code Online (Sandbox Code Playgroud)

或者

mountpoint -q /mnt/foo && echo "mounted" || echo "not mounted"
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考:`mountpoint` 源自 Ubuntu/Debian 中的“initscripts”包。 (5认同)

Ell*_*iew 35

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


其他方法有以下缺点:

  • grep -q并且grep -s是一个额外的不必要的步骤,并非所有地方都支持。
  • /proc/\*并非所有地方都支持。(mountpoint也基于 proc)。
  • mountinfo 基于 /proc/..
  • cut -f3 -d' ' 弄乱路径名中的空格
  • 解析mount的空白是有问题的。它的手册页现在说:

.. 保留列表模式只是为了向后兼容。

要获得更强大和可定制的输出,请使用findmnt (8),尤其是在您的脚本中。


重击函数:

#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
Run Code Online (Sandbox Code Playgroud)

用法示例:

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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,对于 encfs,`findmnt` 必须与参数 `--source encfs` 一起提供,否则它将始终认为要挂载的目录,因为它会回退到父挂载。 (2认同)

chr*_*ris 7

像这样的脚本永远不会是可移植的。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
Run Code Online (Sandbox Code Playgroud)

有点告诉你有用的信息。

  • 这个问题被标记为 linux,所以也许它不必是可移植的 (2认同)

cas*_*cas 7

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

注意:以下仅适用于 linux,因为它 grep /proc/mounts - 更便携的版本将运行 'mount | grep /backup',如马修的回答..

  如果 !grep -q /backup /proc/mounts ; 然后
    如果 !挂载/备份;然后
      回声“失败”
      出口 1
    菲
  菲
  回声“成功了。”
  # 在这里做事

  • Upvoted 作为一个很好的健全性检查替代方案。 (3认同)