私のシェルスクリプトは次のとおりです。
#!/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を終了する必要があります。
process1を終了するのはPIDをファイルに書き込むので簡単です。しかし、sub_process1はそうではありません。 sub_process1はサードパーティのコンポーネントなので、ソースコードに触れることはできません。
sub_process1のPIDを取得するソリューションがあります。
- すべてのプロセスを列挙するには、このコマンドを使用します
ps aux
。 - コマンドを使用して、各プロセスのPPID(親プロセスID)を取得します
ps -f [PID]
。 PPIDがprocess1のPIDと等しい場合、プロセスはsub_process1でなければなりません。
上記の解決策は少し複雑です。子プロセスIDを取得する簡単なソリューションはありますか?
ありがとうございます。
答え1
pgrep
Linux:/とマークしたので、pkill
次のようにします。
PID_OF_SUB_PROCESS1=$( pgrep -P $PID_OF_PROCESS1 )
pkill -P $PID_OF_PROCESS1
答え2
process
バックグラウンドプロセスとして実行してプロセスIDを取得できます。
./process1 &
pid1=$!
wait "$pid1"
コマンドは元のスクリプトと同様に終了をwait
待ちます(子プロセスではありません)。process1
元のスクリプトにprocess1
最後に終了するものはありません。./process1
コマンドはprocess1
終了時にのみ完了します。プロセスには同じ名前の子プロセスがあります(つまり、プログラムfork
しかし、execve
)。process1
スクリプトの開始直後にスクリプトを実行し続ける場合は、この行wait
を省略してください。
お持ちの場合pkill
コマンドは、プロセスのすべての子プロセスを終了する便利な方法です。プロセスはまだ実行中である必要があります。ゾンビそうしないと、子プロセスの親プロセスIDが1にリセットされ、そのように追跡できなくなります。バックグラウンドプロセスIDは、wait
スクリプトから呼び出されない限り有効なままです。
./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"
答え3
君ができるのはkill -TERM
君だけだプロセスグループ。スクリプトがシェルから呼び出されると、スクリプトのPIDと同じ独自のプロセスグループがあります。
kill -TERM -$$
別の方法で呼び出されると、プロセスグループIDがPIDと等しくない可能性があります。
kill -TERM -`ps -o pgid $$ | tail -1`
kill -9
プログラムに公正な機会を提供しない限り、スクリプトやプログラムに参加してはいけませんkill -TERM
。
aを実行するfind pid and kill it
ことは競合状態の影響を受けます(ただし、ボックスがクレイジーなプロセスを作成しない限り頻繁には見えませんが)。pid
あなたが殺すpidがあなたの子供であり、pidが待っていないことによってリサイクルされないことを保証しない限り、sは移動目標です。 (私が知っている限り、bashではほとんどできません)それ以外の場合は、正しいプロセスを終了していないことを100%確信しています(pidを見つけて終了する間にプロセスが終了し、他のプロセスがpidを取得した可能性があります) )。
答え4
setsid ./process1 & pgid=$!
以下を使用して別々のプロセスグループを使用または作成する必要があります。職業管理:set -m; ./process1 & pgid=$!; set +m
次の手順でプロセスグループ全体を終了しますkill -- -$pgid
。追加情報ここ