ボリュームがBashスクリプトにマウントされているかどうかを確認する最良の方法は何ですか?


103

ボリュームがBashスクリプトにマウントされているかどうかを確認する最良の方法は何ですか?

私が本当に欲しいのは、次のように使用できる方法です:

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

これを自分で行うためのスクリプトを作成しようとしていました。最初に考えたのは、/ etc / mtabから情報を取得することです。しかし、bashの本にまだ触れずに、より直接的な方法があるかどうかを確認していません。
3dinfluence 2009

@ 3dinfluence-はい、私は昔からこれを知っていますが/etc/mtab/proc/mountsにリンクされてい/proc/self/mountsます。(少なくとものFedora 20の上にそれがある)
Wilf

同様の質問は、サーバーフォールトスタックオーバーフローUnixおよびLinuxスタック交換に関するものです。
サーシャ

回答:


113

/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です。)


7
言うまでもなく、マウントポイントがウェッジされている場合、mountの呼び出しがハングする可能性があります。
チャドハニーカット2009

8
Linuxに適していますが、freebsdやsolarisには適していません。
クリス

4
これは本当です、クリス。質問にはlinuxというタグが付けられていましたが。
ダンキャリー

3
これは哲学的な質問だと思います-可能であれば、物事をポータブルにしようとするべきですか、それとも世界中のすべてのWindows / Linuxを実行し、それに応じて行動するだけでよいのでしょうか?
クリス

18
実際には、「/ mnt / foo」をテストする必要があります。たとえば、スペースを使用すると、たとえば 「愚か者」。「lmde」と「lmde-home」という2つのマウントポイントで問題が発生しました。
-marlar

58
if mountpoint -q /mnt/foo 
then
   echo "mounted"
else
   echo "not mounted"
fi

または

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

4
参考情報:mountpointUbuntu / Debianの「initscripts」パッケージに由来します。
12

1
役に立たなかった-:-(
Wilf 14年

これは、私のVagrantが待ち望んでいる呼び出しです。
dhill

問題mountpointは、実際にはマウントポイントがマウントされているかどうかをチェックすることですが、デバイスがマウントされているかどうかはチェックしないことです。デバイスが-xオプションで渡される場合、メジャー/マイナーデバイス番号が通知されますが、マウントされている場合は通知されません。
-vegatripy

@blueyed Debian Busterでは、パッケージによって提供されますutil-linux
elboulangero

18

findmnt -rno SOURCE,TARGET "$1"他の回答のすべての問題を回避します。1つのコマンドでジョブをきれいに実行します。


他のアプローチには次のような欠点があります。

  • grep -qそしてgrep -s余分な不要なステップであり、どこでもサポートされていません。
  • /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

使用例:

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

1
とにかくLinux固有の場合、これが本当に最善のアプローチです。私はfindmnt(8)コマンドを見ましたが、実際にそれで遊んだことはありません。率直に言って、Linuxボックス(またはコマンドが利用可能な場所)でこのタイプのことを行う(または新しいスクリプトを作成する)スクリプトの一部を更新する場合、これが私がやることです。
プリフタン

1
encfsの場合findmnt、パラメータ--source encfsを指定する必要があります。指定しない場合、親マウントにフォールバックするため、ディレクトリは常にマウントされていると見なされます。
バーカート

また、これはより優れているgrepマウントパスが奇妙であるならば、あなたは偽陽性を得ることができますので、解決策:私はマウントする場合、たとえば/dev/mmcblk0p1~/mnt/dev/sda1、私は事間違ってできた/dev/sda1コマンドによって実装されていますmount | grep '/dev/sda1'。を使用して誤検出を取得することはできませんfindmnt。いい答えだ!
コーディピアソール

7

このようなスクリプトは、ポータブルになることはありません。unixの汚い秘密は、カーネルだけがどのファイルシステムがどこにあるかを知っているということです。

私は通常dfを使用して、サブディレクトリのマウントポイントとそのサブシステムがどのファイルシステムにあるかを発見します。

例えば(ash / AT&T ksh / bash /などのようなPOSIXシェルが必要です)

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

ちょっと便利な情報を教えてくれます。


1
質問は、Linuxをタグ付けされているので、多分それは、ポータブルである必要はありません
ロリー・

6

以下は、rsyncバックアップcronジョブの1つで使用するものです。/ backupがマウントされているかどうかを確認し、マウントされていない場合はマウントしようとします(ドライブがホットスワップベイにあり、システムに存在しないために失敗する場合があります)

注:以下はLinuxでのみ動作します。/proc/mountsをgrepsするためです-よりポータブルなバージョンでは 'mount | マシューの答えのように、grep / backup '

  もし!grep -q / backup / proc / mounts; それから
    もし!マウント/ backup; それから
      エコー「失敗」
      1番出口
    fi
  fi
  echo "suceeded。"
  #ここで何かをする

2
適切な健全性チェックの代替手段として支持されました。
ダンキャリー

おそらくこの方法は、Matthew Blochの答えと同じ問題にぶつかります。
mwfearnley

ええ、「Eliptical view」で言及されているファイル名のスペースの問題を除きます(これは、抽出されたフィールドだけでなく、行全体を把握します)。引数を引用することはあなたができることであることを何らかの形で忘れない限り、部分文字列の問題は大したことではありません。例えばgrep -q ' /backup ' /proc/mountsまたはmount | grep -q ' /backup '。または、grepがサポートしていない場合は/ dev / nullにリダイレクトします-q(これ最近のgrepのPOSIX仕様にあります)。
cas

2

マウントするためには、とにかくそこにディレクトリが必要であり、それがマウントされるので、私の戦略は、使用されることのない奇妙なファイル名で偽のファイルを作成し、その存在を確認することでした。ファイルがあった場合、その場所には何もマウントされていません...

これは、ネットワークドライブなどのマウントには機能しないと思います。フラッシュドライブに使用しました。


2

デバイス番号の比較はどうですか?私は最も難解な方法を考えようとしていました。

#!/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にもエラーが表示されるためです。


実際、おそらく各呼び出しでまずstatの終了ステータスをチェックして、ファイルがあることを確認する必要があります...私が思ったほど斬新ではありません:
Kyle Brandt

1

これらのいずれも、特定のディレクトリが別のマウントポイント内のサブディレクトリであるユースケースを満たしません。たとえば、host:/ real_thingへのNFSマウントである/ 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

これを持ってきてすみませんが、これはかなり便利だと思います:

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

これにより、/ proc / mountsの2列目が取得されます(2列目=マウントポイント)。

次に、出力を把握します。^と$に注意してください。これは、/ backupが/ mnt / backupや/ backup-oldなどに一致しないようにします。


0

多分あなたのマウントポイントのgrep / etc / mtab?


1
/が読み取り専用であるためにmount -nを使用する場合など、mtabが古くなったり、マウントによって更新されないことがあります。
クリス

同意しますが、それが最初に見始めた場所のように思えました。
オフィディアン


0

これはLinuxの質問ですが、簡単にできたら移植性を高めてみませんか?

のマニュアルページにgrepは:

ポータブルシェルスクリプトは、-qと-sの両方を避け、/dev/null代わりに標準出力とエラー出力をリダイレクトする必要があります。

そこで、次の解決策を提案します。

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

3
多くのUNIXシステムでは、/ procファイルシステムを提供していない
ドミトリChubarov

@DmitriChubarov確かに。移植性の概念を皮肉にしているのはどれですか?そして、おそらくそれはより新しいアップデートですが-q-sPOSIXによって指定されているので、とにかく移植性の問題はないはずです(以前はそうではありませんが、いつ変更が発生するかを追跡していません)。
プリフタン

0

これよりも複雑にする必要がありますか?

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

1
grep -q /mnt/fooまた、マウントポイント/mnt/foodと一致し/not/mnt/fooます...どうgrep -qx /mnt/fooですか?
rakslice

@rakslice:それは機能しません。-x行全体が一致する場合にのみgrepを一致させます。
mivk

1
cut -f 3 -d ' 'マウントパスにファイル名にスペースがあるとつまずきます。
楕円ビュー

0

確認しているボリュームに関する知識に依存します。

最近調査した特定のケースでは、特定のフラッシュドライブがマウントされているかどうかを確認するのが心配でしたが、最も簡単に機能するのは/ dev / disks / by-label /の存在を確認することです。デバイスが接続されている場合、udevスクリプトはリンクが存在することを確認します(デバイスが接続解除されると削除されます)。

(これは移植性の高い答えではありません。しかし、多くの最新のLinuxディストリビューションで機能し、Linuxの質問にタグが付けられました。これまで述べてきたものとはまったく異なるアプローチなので、可能性が広がります。)


0

マウントポイントの下にファイルを作成しcheck_mount、それが存在するかどうかをテストしますか?

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

-1

chef-clientが実行されると、ボリュームが既にマウントされているために実行が失敗するため、べき等性のためにChefでこれを行う必要がありました。この記事を書いている時点では、Chef mountリソースには何らかのバグがあり、必要な属性では機能しません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


...そして、これは元の質問と何の関係がありますか?!?
マッシモ

私のシェフのレシピのコメントと元の質問との関係は、人々がますます自動化に向かっているということです。したがって、誰かがシェフのレシピでこの作業を行う方法を知りたいとここに来た場合、彼らは答えを持っています。人生には2つの選択肢があります。1)最低限のことをして、何人かの人々を幸せにします。したがって、投稿をマークダウンする代わりに、それが何であるかを受け入れます。受け入れられた答えをサポートする追加情報。
クラウ

質問はbashスクリプトについてでした。あなたの答えはChefスクリプトについてです。誰かにとっては役に立つかもしれませんが、それでも質問とは無関係です。
マッシモ

@KLaw 「したがって、私の投稿をマークダウンする代わりに、それが何であるかを受け入れてください。受け入れられた答えをサポートする追加情報。」私は同意し、通常は賛成票を投じるわけではありません(そして私もここにはいません)が、その種の問題がある場合は、他のポイントに追加する必要がありますか?他のコメントを保存する場合があります。しかし、自動化に関しては、bashスクリプトで許可されていることとまったく同じであるため、ポイントを確認できません。もちろん、私のプログラマーは、上記のスクリプトは恐ろしいと思いますが、それは他の何よりも言語の問題です
...-Pryftan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.