Linuxでコマンドの使用を待ちますか?


16
#!/bin/bash
function back()
{
    sleep $1
    exit $2
}
back $1 $2 &
b=$!
if `wait $!`;then
    echo success
else
    echo failure
fi
bash-3.00# ./back 300 0
failure
bash-3.00# ./back 300 1
failure

success0を送信するときに終了ステータスとして期待していましたが、まだ取得していfailureます。

また、wait300秒待機しません。代わりに、すぐにメッセージを受け取ります。私は仮定$!の直接の子である$$私のスクリプトインチ そうじゃない?

のような待機の終了ステータスをキャプチャすることは可能exit_status=$(wait $!)ですか?

if ! ((exit_status));then
    echo sucess
else
    failure
fi

回答:


20

問題はwait、サブシェルで発行していることです:

if `wait $!`;then

のでwait組み込み、ないコマンドです、それは上で動作だサブシェルではなく、あなたの現在のシェル。

表示されるが、表示されない出力は次のとおりです。

wait: pid 12344 is not a child of this shell

...戻りステータス1。

テストを実行するには、サブシェルを使用せずにテストを実行する必要があります。

#!/bin/bash
function back()
{
  sleep $1
  exit $2
}
back $1 $2 &
b=$!

wait $b && echo success || echo failure

これにより、期待どおりの結果が得られ、期待する限り待機します。

$ time ./test.sh 3 0
success
./test.sh 3 0  0.00s user 0.01s system 0% cpu 3.012 total
$ time ./test.sh 3 1
failure
./test.sh 3 1  0.00s user 0.01s system 0% cpu 3.012 total

次のコマンドを使用して、コマンドの終了ステータスを確認できます。 $?

$ /bin/true
$ echo $?
0
$ /bin/false
$ echo $?
1

スクリプトに他のエラーがいくつかありました。あなたの#!回線の形式が正しくありませんでしたが、修正しました。に割り当てます$!$b、使用しないでください$b


12

バックティックを取り外します。

wait現状では、親シェルのジョブにアクセスできないサブシェルで実行しているため、すぐに失敗します。


終了ステータスが必要な場合は$?、待機直後の値を取得します。

command_here &
wait
status=$?

2

バックティックを削除すると、プログラムが機能しますが、すでに特定されている理由のためではありません。は本当だwait、それはサブシェルで実行され、その親のプロセスにアクセスすることはできませんが、あなたが仕事をしたコマンドを使用しても、期待通りのプログラムが実行されませんので、すぐに失敗します。

このifステートメントはプログラムを実行し、その終了ステータスがゼロまたは非ゼロかどうかを確認します。バックティックを使用する場合、ifステートメントはプロセスの出力を取得し、プログラムとして実行しようとし、そのプロセスの終了コードを使用します。したがって、プログラムは失敗するためwait失敗しませんが、むしろ失敗するためですwaitはなく、出力を生成しないためします。

echoバックティック内で使用することにより、スクリプトを機能させることができます。

if `echo wait $!`; then
    echo success
else
    echo failure
fi

または、単にバックティックを削除します。誰にとっても簡単です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.