GNU/Linux >> Linux の 問題 >  >> Linux

Bash:タイムアウトで待機

あなたの例と受け入れられた答えの両方が非常に複雑です。なぜのみ timeout を使用 まさにだから そのユースケース? timeout コマンドには組み込みのオプションもあります (-k ) SIGKILL を送信する コマンドを終了する最初のシグナルを送信した後 (SIGTERM デフォルトでは) 最初のシグナルを送信した後もコマンドが実行中の場合 (man timeout を参照) ).

スクリプトが必ずしも wait を必要としない場合 待ってから制御フローを再開します。

timeout -k 60s 60s app1 &
timeout -k 60s 60s app2 &
# [...]

ただし、その場合は timeout を保存するだけで簡単です 代わりに PID:

pids=()
timeout -k 60s 60s app1 &
pids+=($!)
timeout -k 60s 60s app2 &
pids+=($!)
wait "${pids[@]}"
# [...]

$ cat t.sh
#!/bin/bash

echo "$(date +%H:%M:%S): start"
pids=()
timeout 10 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 1 terminated successfully"' &
pids+=($!)
timeout 2 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 2 terminated successfully"' &
pids+=($!)
wait "${pids[@]}"
echo "$(date +%H:%M:%S): done waiting. both jobs terminated on their own or via timeout; resuming script"

.

$ ./t.sh
08:59:42: start
08:59:47: job 1 terminated successfully
08:59:47: done waiting. both jobs terminated on their own or via timeout; resuming script

PID をファイルに書き込み、次のようにアプリを起動します:

pidFile=...
( app ; rm $pidFile ; ) &
pid=$!
echo $pid > $pidFile
( sleep 60 ; if [[ -e $pidFile ]]; then killChildrenOf $pid ; fi ; ) &
killerPid=$!

wait $pid
kill $killerPid

これにより、タイムアウトのためにスリープし、それまでに完了していない場合はそのプロセスを強制終了する別のプロセスが作成されます。

プロセスがより速く完了すると、PID ファイルが削除され、キラー プロセスが終了します。

killChildrenOf すべてのプロセスをフェッチし、特定の PID のすべての子プロセスを強制終了するスクリプトです。この機能を実装するさまざまな方法については、この質問の回答を参照してください:すべての子プロセスを強制終了する最良の方法

BASH の外に出たい場合は、PID とタイムアウトをディレクトリに書き込んで、そのディレクトリを監視できます。約 1 分ごとにエントリを読み、どのプロセスがまだ残っているか、タイムアウトになっているかどうかを確認してください。

編集 プロセスが正常に終了したかどうかを知りたい場合は、kill -0 $pid を使用できます。

EDIT2 または、プロセス グループを試すこともできます。 kevinarpe は言った:PID(146322) の PGID を取得するには:

ps -fjww -p 146322 | tail -n 1 | awk '{ print $4 }'

私の場合:145974. その後、PGID を kill の特別なオプションと共に使用して、グループ内のすべてのプロセスを終了できます:kill -- -145974


Linux
  1. Bash -cと位置パラメータ?

  2. タイムアウトと同等のwaitpid?

  3. bashスクリプトにスペースを含むベース名?

  1. XPATH を使用した Linux Bash XMLLINT

  2. Bashでbcを使用して数値を丸める

  3. Bash でコマンドのグループをタイムアウトする方法

  1. 例を含む Bash 配列

  2. 例を含む Bash If-Else ステートメント

  3. poll() はタイムアウト 0 で何をしますか?