web-dev-qa-db-ja.com

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

_#!/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
_
16
munish

問題は、サブシェルで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は使用しないでください。

20
bahamat

バックティックを削除します。

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


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

command_here &
wait
status=$?
12
Patrick

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

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

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

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

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

2
Joni