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

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

我真的很喜欢这样一种方法,我可以这样使用:

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

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

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

只是:

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

要么

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

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

我通常使用df来发现子目录的挂载点以及它所在的文件系统。

例如(需要像灰/ AT&T ksh / bash /等posix shell)

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

有点告诉你有用的信息。

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

注意:以下只适用于linux,因为它是greps / proc / mounts – 一个更便携的版本会运行'mount | grep / backup“,正如马修的回答。

  如果!  grep -q / backup / proc / mounts; 然后
    如果!  mount / backup; 然后
      回声“失败”
      出口1
    科幻
  科幻
  回声“成功”。
   #在这里做东西

因为为了装载,你需要有一个目录在那里,我的策略总是创build一个奇怪的文件名,永远不会被使用的伪造文件,只是检查它的存在。 如果那个文件在那里,那么在那个地方什么都没有装上…

我不认为这适用于安装networking驱动器或类似的东西。 我用它的闪存驱动器。

比较设备号码如何? 我只是想想最深奥的方式..

 #!/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 

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

这些都不满足给定的目录是另一个挂载点内的子目录的用例。 例如,你可能有一个NFS挂载的东西:/ real_thing。 在/ proc / mounts / etc / mtab或'mount'上使用grep是不行的,因为你将会寻找一个不存在的挂载点。 例如,/ thing / thingy不是挂载点,但是/东西挂载在主机:/ 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 

这是非常有用的,如果你想创build一些chroot镜像chroot之外的挂载点,在chroot中,通过一些任意的目录或文件列表。

对不起,提出这个,但我认为这是非常有用的:

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

这将得到/ proc / mounts的第二列(第二列=挂载点)。

然后它会输出结果。 注意^和$,这可以防止/备份匹配/ mnt / backup或/ backup-old等

你的挂载点的grep / etc / mtab也许?

这个?:

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

来自: 一个Ubuntu论坛

虽然这是一个Linux问题,但为什么在轻松完成的时候不能轻易移植呢?

grep的手册页说:

可移植的shell脚本应避免-q和-s,并应将标准错误输出redirect到/dev/null

所以我提出以下解决scheme:

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

它是否需要比这更复杂?

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

我不得不在Chef中这样做,因为当厨师客户端运行时,由于卷已经被挂载,运行将失败。 在我写这篇文章的时候,Chef mount资源有一些bug,不能按照我需要的方式处理属性,所以我使用execute资源来挂载这个卷。 以下是我如何做到的:

 if not node['docker-server']['mountpoint'] == "none" execute "set up mount" do user "root" command "mount -t ext4 #{node['docker-server']['mountpoint']} #{node['docker-server']['data-dir']}" not_if "grep -qs #{node['docker-server']['data-dir']} /proc/mounts" end end 

如果有任何混淆,在我的属性文件中,我有以下几点:

 default['docker-server']['mountpoint'] = "/dev/vdc" default['docker-server']['data-dir'] = "/data" 

if not node['docker-server']['mountpoint'] == "none"case语句的一部分,如果未指定服务器上的装入点,则装入点默认为none