_#!/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
_
0を送信すると、終了ステータスとしてsuccess
を期待していましたが、まだfailure
を取得しています。
また、wait
は300秒間待機しません。代わりに、すぐにメッセージが表示されます。私のスクリプトでは、_$!
_が_$$
_の直接の子であると想定しています。だよね?
exit_status=$(wait $!)
のように待機の終了ステータスをキャプチャすることは可能ですか?
_if ! ((exit_status));then
echo sucess
else
failure
fi
_
問題は、サブシェルで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
は使用しないでください。
バックティックを削除します。
現状では、親シェルのジョブにアクセスできないサブシェルでwait
を実行しているため、すぐに失敗します。
終了ステータスが必要な場合は、待機の直後に$?
の値を取得します。
command_here &
wait
status=$?
バッククォートを削除するとプログラムが機能しますが、すでに特定されている理由のために完全にではありません。 wait
はサブシェルで実行され、その親のプロセスにアクセスできないため、すぐに失敗しますが、機能するコマンドを使用しても、プログラムは期待どおりに実行されません。
if
ステートメントはプログラムを実行し、その終了ステータスがゼロか非ゼロかを確認します。バックティックを使用すると、ifステートメントはプロセスのoutputを取得し、プログラムとして実行してから、そのプロセスの終了コードを使用します。したがって、wait
が失敗してもプログラムは失敗しませんが、wait
が出力を生成しないため失敗します。
バックティック内でecho
を使用して、スクリプトを機能させることができます。
if `echo wait $!`; then
echo success
else
echo failure
fi
または、単にバックティックを削除します。誰にとっても簡単です。