私のシェルスクリプトは次のとおりです。
#!/bin/bash
./process1 #It will create a sub process: sub_process1
while [ condition ]; do
break
done
kill -9 process1 and sub_process1
私のスクリプトでは、プロセスを作成します:process1。 process1はサブプロセスを作成します:sub_process1。
スクリプトが終了する前に、process1とsub_process1を強制終了する必要があります。
PIDをファイルに書き込むため、process1を簡単に強制終了できます。しかし、sub_process1はしません。 sub_process1はサードパーティのコンポーネントなので、ソースコードを変更することはできません。
sub_process1のPIDを取得できるソリューションがあります:
ps aux
;を使用してすべてのプロセスを列挙します。ps -f [PID]
を使用して、各プロセスのPPID(親プロセスID)を取得します。 PPIDがprocess1のPIDと等しい場合、プロセスはsub_process1である必要があります。これをLinuxとしてタグ付けしたので:pgrep
/pkill
が救助に:
PID_OF_SUB_PROCESS1=$( pgrep -P $PID_OF_PROCESS1 )
pkill -P $PID_OF_PROCESS1
pkill
はプロセスを強制終了できます名前で:
pkill process1 && pkill sub_process1
仕事をする必要があります。
バックグラウンドプロセスとして実行することにより、process
のプロセスIDを取得できます。
./process1 &
pid1=$!
wait "$pid1"
wait
コマンドは、元のスクリプトと同様に、process1
が終了するのを待ちます(ただし、そのサブプロセスは待ちません)。元のスクリプトでは、最後に強制終了するprocess1
がないことに注意してください。./process1
コマンドは、process1
が終了したときにのみ終了します。同じ名前のそのプロセスの子プロセスが存在する可能性があります(つまり、プログラムが fork
を呼び出したが、 execve
を呼び出さなかった可能性があります)。 process1
自体が開始されたらすぐにスクリプトの実行を継続する場合は、wait
行を省略してください。
pkill
コマンドがある場合は、プロセスのすべての子を強制終了するのに便利な方法です。プロセスはまだ実行中であるか、 zombie である必要があることに注意してください。そうしないと、子の親プロセスIDが1にリセットされ、この方法で追跡できなくなります。スクリプトでwait
を呼び出さない限り、バックグラウンドプロセスIDは有効なままです。
./process1 &
pid1=$!
…
pkill -9 -P "$pid1"
kill -9 "$pid1"
プロセス、その子、およびその子を再帰的に追跡する別の方法は、 プロセスグループ を追跡することです。プロセスの子は、明示的に変更しない限り、同じプロセスグループを持ちます。 Linuxでは、 setsid
コマンドを使用して、独自のプロセスグループでプログラムを実行できます。プロセスグループは、元のプロセスのプロセスIDによって識別されます。プロセスグループ内のすべてのプロセスを強制終了するには、プロセスグループIDの負の値をkill
に渡します。
setsid ./process1 &
pgid1=$!
…
kill -9 "-$pgid1"
プロセスを追跡するさらに別の方法は、プロセスにファイルを開かせることです。これは、プロセスがファイルを閉じない限り機能するため、デーモンとして実行することを目的としたプログラムでは機能しない可能性があります。コマンド fuser
を使用して、ファイルを開いているプロセスを強制終了します。
tmpfile=$(mktemp)
process1 <"$tmpfile"
…
fuser -k -9 "$tmpfile"
あなたにできることはkill -TERM
you プロセスグループです。スクリプトがシェルから呼び出された場合、スクリプトのPIDと等しい独自のプロセスグループがあります。
kill -TERM -$$
それ以外の方法で呼び出された場合、そのプロセスグループIDはそのPIDと等しくない可能性があります。
kill -TERM -`ps -o pgid $$ | tail -1`
スクリプトにkill -9
を使用しないでください。ただし、kill -TERM
を使用してプログラムに公平な機会を与える場合を除きます。
find pid and kill it
の実行は、競合状態の影響を受けます(ただし、ボックスがクレイジーなプロセスを生成しない限り、頻繁に実行されるわけではありません)。 pid
sは動くターゲットであり、あなたが殺しているpidがあなたの子供であり、まだそれを待たないことによってpidがリサイクルされないことを保証していない限り(bashではほとんどできないことです)私は知っています)、あなたが正しいプロセスを殺していることを100%確信することはできません(pidを見つけて殺すまでの間に、プロセスが死んで、別のプロセスがpidを取っているかもしれません)。