いくつかの子プロセスを生成するbashスクリプトを作成しており、1時間ごとにcron
ジョブによって実行されます。実際には、リモートサーバーに対してrsync
コマンドと、関連するssh
接続を実行しています。
Rsyncコマンドまたはスクリプトに時間がかかりすぎる場合、それとその子プロセスを強制終了しますが、最初に猶予期間を与えます。スクリプトは1時間ごとに実行されますが、次の2回の試行では、スクリプトの前のインスタンスが実行中であることがわかり、転送を開始する前に終了します。 3回目以降の試行は、新しい転送を開始する前に、まだ実行中の元のインスタンスを強制終了します。
PIDファイルに書き込むことでこれを制御することにしました。最初のインスタンスはそのPIDをファイルに書き込み、次の2回の試行は終了する前にPIDをファイルに書き込みます。 3回目の試行で最初の試行が強制終了され、PIDファイルが新しいPIDで上書きされます。正常に完了すると、PIDファイルが消去されます。すべての子供を殺すために、私は私が取得する元のスクリプトインスタンスのPGIDを使用することにしました:
previous_pid=$(head -n1 "$pid_file")
previous_groupid=$(ps -hp "$previous_pid" -o pgid:1)
それからそれを殺します:
kill -- -"$previous_pid"
私の懸念は、PIDファイルをクリーンアップせずに元のスクリプトが何らかの理由で停止し、PGIDを再利用するPIDが再利用されている状態になる可能性があるため、完全に無関係なプロセスを強制終了することです。 どうすればこれを回避できますか?
スクリプトを取得して自分自身を殺します。たとえば、スクリプトの最初に次のようなものがあります。
kill_myself () {
while sleep 1
do
if [[ -f /tmp/kill-myself ]]
then
rm /tmp/kill-myself
kill -- -$1
fi
done
}
kill_myself $$ &
今、時が来たら:
touch /tmp/kill-myself
これをカスタマイズして、スクリプトの各インスタンスに独自のキルファイルを持たせ、どこかにログを記録することができます。次に、そのファイルを使用して、スクリプトの特定のインスタンスを強制終了します。
別の方法:pgrep
/pkill
を使用して、より詳細に一致させることができます。 pidファイルから読み取り、コマンド名や引数などと照合できます。
次のようなものは、スクリプトと同じ名前のプロセスのみを強制終了します(script-name
または/path/to/script-name
として呼び出した場合)。
pkill -g "$previous_groupid" script-name
bash script-name
を実行すると、これは機能しません。または、単にrsync
コマンドを強制終了します。これにより、おそらくスクリプトはその後終了します。
pkill -g "$previous_groupid" rsync