GNU coreutilstimeout
コマンドは、特定のスクリプト状況で非常に便利です。コマンドが高速に実行されている場合にコマンドの出力が消費されることを許可する場合、またはコマンドの実行に時間がかかりすぎる場合は、スキップしてください。
timeout
POSIX仕様のみを使用してユーティリティのデフォルト動作をどのように大まかに計算できますか?
wait
sleep
(私はそれが、、の組み合わせを含むことができると思ったし、何を知っているのかわからないが、kill
より簡単な方法を逃したかもしれない。)
答え1
私のアプローチは次のとおりです。
バックグラウンドプロセス1でコマンドを実行する
バックグラウンドプロセス2で「ウォッチドッグタイマー」を実行
親シェルで終了信号を取得するようにハンドラを設定します。
両方のプロセスが完了するのを待ちます。最初に終了するプロセスは、親プロセスに終了信号を送信します。
親プロセスのトラップハンドラは、ジョブ制御を介して両方のバックグラウンドプロセスを終了します(プロセスの1つが定義に従って終了しましたが、PIDを使用しないため、終了は無害です。以下を参照)。
システムPIDの代わりに終了するバックグラウンドプロセスを識別するために、シェルのジョブ制御ID(このシェルインスタンスに明示的に指定されている)を使用してコメントに記載されている可能性のある競合状態を回避しようとしています。
#!/bin/sh
TIMEOUT=$1
COMMAND='sleep 5'
function cleanup {
echo "SIGTERM trap"
kill %1 %2
}
trap cleanup SIGTERM
($COMMAND; echo "Command completed"; kill $$) &
(sleep $TIMEOUT; echo "Timeout expired"; kill $$) &
wait
echo "End of execution"
結果TIMEOUT=10
(ウォッチドッグの前にコマンドが終了しました):
$ ./timeout.sh 10
Command completed
SIGTERM trap
End of execution
結果TIMEOUT=1
(コマンドの前にウォッチドッグが終了しました):
$ ./timeout.sh 1
Timeout expired
SIGTERM trap
End of execution
結果TIMEOUT=5
(ウォッチドッグとコマンドが「ほぼ」同時に終了しました):
./tst.sh 5
Timeout expired
Command completed
SIGTERM trap
End of execution