「ガベージコレクタ」をカスタマイズして、プログラムを手動で閉じます。

「ガベージコレクタ」をカスタマイズして、プログラムを手動で閉じます。

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秒に増やします。

おすすめ記事