Bashスクリプト-戻り値が0になるまでループする


25

スクリプトで何かをアンマウントする必要がありますが、すべてのデータのコピーが完了してアンマウントが失敗する前にアンマウントされることがあります。「ブロッキング」マウントを行う方法を探しましたが、何も見つかりませんでした。そのため、アンマウントできるようになるまでループするスクリプトを作成しようとしましたが、機能しません。

while [ `sudo umount mount` ]
do
    sleep 0.1
done
rmdir mount

実行出力の場合:

umount: /home/evantandersen/mount: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
rmdir: failed to remove `mount': Device or resource busy

の戻り値sudo umount mountが0になるまでループしないでください。つまり、正常にアンマウントされました。

回答:


59

[コマンドは、条件式を評価することです。ここでは役に立たない。

umount標準出力には何も出力されないため(エラーはstderrに送られます)、`sudo umount mount`何も展開されません。

それは次のようなものです:

while [ ]
do
  sleep 0.1
done

[横に任意の引数を渡されていないコマンド、[および]リターンの偽のあなたがループに入らないので、(ゼロ以外の終了状態)。

たとえumount使用して標準出力にそのエラーを持っていた出力、[その出力の結果の単語が有効な条件式を作ったことはなかっただろうのでコマンドは、意味をなさなかっただろう。

ここにあなたが欲しい:

until sudo umount mount
do
  sleep 0.1
done

つまり、コマンドではなく、sudo / umountの終了ステータスを確認する必要があります[

umountstderrにエラーまたは警告が出力されるかどうかを確認したい場合は、それ[が役に立つはずです。-n "some-string"認識条件式である[かどうかをテストするには、コマンド"some-string"、空であるかどうか何かのようなので:

while [ -n "$(sudo umount mount 2>&1 > /dev/null)" ]; do
  sleep 0.1
done

しかし、エラーまたは警告メッセージの存在を探すことは一般に悪い考えです。このumount コマンドは、終了コードで成功するかどうかを示し、より信頼性が高くなります。成功しても、警告メッセージが出力される可能性があります。失敗し、エラーが出力されない可能性があります(強制終了された場合など)。

この特定のケースでumountは、ディレクトリがマウントされていないため失敗する可能性があり、その場合は永久にループするため、次のような別のアプローチを試すことができます。

while mountpoint -q mount && ! sudo umount mount; do
  sleep 0.1
done

または、「mount」が複数回マウントされ、それらすべてをアンマウントする場合:

while mountpoint -q mount; do
  sudo umount mount || sleep 0.1
done

うまくいきました!
charliehorse55

1
+1を使用[する[[かどうかの違いを説明します。私は、典型的なmanページを願っGNUおよび/または、bashの条件式についてTLDPの例は、このような詳細をカバー
renoirb

5

再利用可能な関数で、「n」秒でタイムアウトします

_umount() {
    [[ $# -lt 2 ]] && { 
        echo "Usage: ${FUNCNAME} <timeout_secs> <mnt_point>"; return 1
    }
    timeout=$(($(date +%s) + ${1}))
    until umount "${2}" 2>/dev/null || [[ $(date +%s) -gt $timeout ]]; do
       :
    done
}

寝る必要はありません


1
[[...]]あるksh/ bash/ zsh持っているすべてが、特定の、$SECONDSあなたができるので、特別な変数は:SECONDS=0; until umount... || ((SECONDS > $1)); do..
ステファンChazelas

ことを覚えておいてくださいmount remount,roINTENSOマイクロラインのUSBスティックとMIPSデバイス安野2009コマンドが取ることができる23あるいは30秒以上を完了させます。
プロバックアップ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.