スクリプトで何かをアンマウントする必要がありますが、すべてのデータのコピーが完了する前にアンマウントして、アンマウントが失敗することがあります。 「ブロッキング」アンマウントを行う方法を探しましたが、何も見つかりませんでした。そのため、アンマウントできるようになるまでループするスクリプトを作成しようとしましたが、機能しません。
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になるまでループしないでください。つまり、正常にアンマウントされました。
[
コマンドは、条件式を評価するためのものです。ここでは役に立たない。
umount
は標準出力に何も出力しないため(エラーはstderrに送られます)、`Sudo umount mount`
は何も展開しません。
だからそれは次のようなものです:
while [ ]
do
sleep 0.1
done
[
コマンドは、[
および]
以外の引数が渡されない場合、false(ゼロ以外の終了ステータス)を返すため、ループに入ることができません。 。
umount
がstdoutにエラーを出力したとしても、[
コマンドを使用しても意味がありません。その結果として得られた単語が有効な条件式を構成することはなかったからです。
ここにあなたが欲しい:
until Sudo umount mount
do
sleep 0.1
done
つまり、[
コマンドではなく、Sudo/umountの終了ステータスを確認する必要があります。
umount
がstderrにエラーまたは警告を出力したかどうかを確認したい場合は、[
が役に立ちました。 -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
再利用可能な関数であり、「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
}
寝る必要はありません