プロセスをバックグラウンドで起動して、bashスクリプト内でいつ終了するかを確認するにはどうすればよいですか?私の考えは次のようなスクリプトです:
launch backgroundprocess & while [ Process is running ];do echo "PROCESS IS RUNNING\r" done; echo "PROCESS TERMINATED"
回答
重要なのは「待機」コマンド:
#!/bin/bash /my/process & /another/process & wait echo "All processes done!"
コメント
回答
wait
必要な粒度を設定できます:
sleep 1 & PID1=$! sleep 2 & PID2=$! wait $PID1 echo "PID1 has ended." wait echo "All background processes have exited."
回答
これを行う1つの方法は次のとおりです。
launch backgroundprocess & PROC_ID=$! while kill -0 "$PROC_ID" >/dev/null 2>&1; do echo "PROCESS IS RUNNING" done echo "PROCESS TERMINATED" exit 0
コメント
- ありがとうございます、これは間違いなく、元の質問の私の解釈(および私がこの質問を見ることになった理由)に答える唯一の答えです。
- @cuonglm、複数のプロセスは何ですか?おそらく
wait
の方が適していますか? - @cuonglmコマンドを強制終了する-0オプションは何をしますか
- @k_vishwanathプロセスかどうかを報告しますまだ実行中かどうか。
回答
nohupを使用してプロセスを実行し、シェルスクリプトを記述して読み取ることができます。 nohupがログに記録するために使用するnohup.outファイル。
nohup command &
コメント
- (1)髪を裂くリスクがあるため、
nohup
は'何もnohup.out
に書き込みません。ファイルを作成し、コマンドの出力をそのファイルにリダイレクトするだけです。 (2)コマンドが'出力を生成しない場合、nohup.out
には何も書き込まれず、このアイデアはどこにも速く行きません。 (3)command
が出力を書き込んだとしても、その出力を監視することで、いつ終了したかをどのように知ることができますか? - @ G-
lsof
の出力をチェックして、nohup
がまだnohup.out
を使用しているかどうかを確認します。しかし、これは非常に厄介な方法であることに同意します。 - (4)
command
が実行を開始するまでに、nohup
はなくなりました。 (1)はい、2年前に言ったことを繰り返しているので、番号を繰り返しています。nohup
はnohup.out
。 (5)はい、lsof
をループして実行するシェルスクリプトを記述して、nohup.out
がまだ開いているかどうかを確認できます。しかし、それは別の答えになります。 (6)それをやったとしても、それは信頼できないでしょう。他のプロセスがnohup.out
ファイルを開いた場合はどうなりますか?この特定のプロセスでnohup.out
が開いているかどうかを確認する必要があります。 (7)しかし、そうする場合は、プロセスが実行されているかどうかを確認してみませんか?
回答
wait
は、同じシェルで起動された子プロセスに対してのみ機能します。それは「結局のところシェル関数です。
任意のバックグラウンドプロセスでは、PIDを使用する必要があります。ここで誰も言及していないのはカーネル PIDリサイクルです。最近のLinuxシステムはPIDをかなり再利用する可能性があります多くの場合、負荷によって異なります。プロセスを確実に識別するには、PID以上のものが必要です。 1つの簡単なアプローチは、時間を節約することです。プロセスが開始されたとき、現在のプロセス開始時間と定期的に比較します。PIDをリサイクルする場合、その開始時間は同じではありません。
プロセス開始時間は / proc / [pid] / stat ファイル。時間は jiffies (最大10ms)で測定されます。プロセスIDのリサイクルを検出する精度。
PID=<process ID> START_TIME=$(cut -d " " -f 22 /proc/$PID/stat) while [ "$(cut -d " " -f 22 /proc/$PID/stat 2>/dev/null)" = "$START_TIME" ]; do echo "PROCESS IS RUNNING" sleep 1 done
cmd1 & p=$!; cmd2 & q=$!; while sleep 1; do echo still running ; done& wait $p $q; kill $!;