Ubuntu 16.04を実行しています。
このプロセスXは複数のttyで実行されています。 screenコマンドを使用して他の疑似端末で実行し、crontabでも実行します。
このプログラムはbashスクリプトから始まるPythonスクリプトから始まります。
時々、Pythonスクリプトは私がキャッチできない例外を発生させ、プロセスXを実行し続けます。
Bashスクリプトの最後でこのプロセスXを終了したいが、他の端末で実行されている他のXプロセスは終了しないでください。
-tパラメーターを使用している他の端末とは無関係のXを処理するためにpgrepを使用しようとしましたが、文書の構文を理解できませんでした。
ベストアンサー1
Pythonコードの新しいプロセスグループを起動します(使用setsid
ユーティリティ)と他のすべての起動プロセス(アプリケーション自体を含む)が含まれているため、必要に応じてプロセスグループ全体を終了できます。
これを行うには、次の設定を使用できます。
exec 3>&1
pgid=$(exec setsid bash -c 'echo $$; exec >&3-; exec COMMAND...')
COMMAND...
通常実行するコマンドとその引数はどこにありますか?一重引用符内にあり、実行するコマンドは文字列(通常のシェル式ではない)として評価できる必要があります。
最初のリダイレクトでは、3>&1
標準出力記述子を記述子 3 にコピーします。リダイレクトは>&3-
記述子 3 を標準出力に移動します。
標準出力に書き込まれたデータを実行して評価します$(...)
。...
上記では、標準出力をシェル変数として読みましたpgid
。
サブシェル(...
)は次に置き換えられました。setsid
新しいセッション(プロセスグループ)でその引数を実行するユーティリティ。ここでは実行しbash
、現在のプロセスPID()を印刷し$$
、元のstdoutを記述子3から戻し、実行に必要なすべてをそれ自体に置き換えますCOMMAND...
。
シェルは実行中にその行を実行し、自己COMMAND...
終了後にのみ次の行に進みます。COMMAND...
COMMAND...
偽のプロセスがまだ実行中であり、それを終了したい場合は、実行するだけです。
kill -SIGNAL -$pgid
問題はどんな信号を送るかである。KILL
プロセスグループの残りのプロセスをすぐに終了するので、これは最も簡単なオプションです。ただし、プロセスが正しく機能している場合は、次のことができるはずです。尋ねる彼らに信号を送ってやめてくださいTERM
。もちろん、時にはプロセスが不安定な状態で反応しないため、編集が必要になることTERM
がありますKILL
。この問題を解決するには、小さなループを使用して残りのプロセスがps
あるかどうかを確認できます。
retries=50
while ((1)); do
# Processes left?
left=$(ps -o pid= -s $pgrp)
[ -n "$left" ] || break
# Ask them to terminate.
kill -TERM $left
# Wait 0.1 seconds.
sleep .1
# Decrement the retry counter.
((--retries > 0)) || break
done
# If there are any processes left in the group,
# send them a KILL signal.
left=$(ps -o pid= -s $pgrp)
[ -n "$left" ] && kill -KILL $left
50回の再試行(それぞれ0.1秒)は、終了信号を送信する前に最大5秒だけ待つことを意味します。これは、アプリケーションとアプリケーションが実行されるハードウェアの種類によっては、適切な値ではない可能性があります。たとえば、コンピュータがラップトップであり、アプリケーションがいくつかの履歴を保存したり、複数のファイルにログインし、ドライブがシャットダウンポイントからスリープ状態になった場合は、遅延時間を約15〜30秒に増やします。