バックグラウンドでコマンドを実行すると、タイムアウト終了コードをどのように取得できますか?

バックグラウンドでコマンドを実行すると、タイムアウト終了コードをどのように取得できますか?

pingコマンドのタイムアウト値の設定中にバックグラウンドでpingコマンドを実行するためのシェルスクリプトを作成しており、タイムアウトのためにpingが終了したときに終了コードを取得したいと思います。以下を使用しています。

timeout 10s ping -c 5 www.google.com | awk '{print "from local to google |", $0;}' &
exit_status=$?
echo $exit_status

しかし、返された終了コードは "&"であり、コマンドがタイムアウトするのではなくバックグラウンドで実行されていることがわかりました。

タイムアウト終了コードをどのように取得できますか?

ベストアンサー1

ここには多くの問題があります。まず、timeoutaをパラメータとして使用します。単一コマンド。だから文章を書くとき

timeout 10s ping -c 5 www.google.com | awk '{print "from local to google |", $0;}'

何が起こるかは、次のようになります。

( timeout 10s ping -c 5 www.google.com ) | awk '{print "from local to google |", $0;}'

つまり、パイプ全体ではなくtimeoutkillpingなのでパイプの終了コード (つまり、 の終了コードawk) を取得します。

終了コードを取得するにはtimeoutサブシェルが必要です。ただし、timeout単一のコマンドをパラメータとして使用するため、明示的に作成する必要があります。

timeout 10 sh -c 'ping ... | awk ...' sh

awkあるいは、パイプライン(たとえば)の最後のコマンド時間を計算することもできます。

ping ... | timeout 10 awk ...

これはうまく機能しますping | awkが、他のコマンドでは競合状態が発生する可能性があります。ping多くの出力が生成されると、リスナーを終了するために使用されるSIGPIPEを受け取ることもできます。

あなたの質問に戻り、これらすべてをバックグラウンドに置きたいと思います。バックグラウンドコマンドの終了コードを取得するには、次の手順を実行する必要がありますwait

timeout 10 sh -c 'ping ... | awk ...' sh &
wait $!
echo $?

残念ながら、バックグラウンドでコマンドを実行する目的を無効にするbashasyncはありません。waitただし、この前に他のコマンドを実行できますwait

おすすめ記事