質問

ループで並列処理を行うバッシュスクリプトがあります。並列プロセスがCPUをスパイクすることを望まないので、睡眠コマンドを使用します。これが簡素化されたバージョンです。

(while true;do sleep 99999;done)&

そこで、上記の行をバッシュプロンプトから実行して、次のようなものを取得します。[1] 12345

どこ [1] ジョブ番号です 12345 whileループのプロセスID(PID)です。私はします kill 12345 取得:

[1]+  Terminated              ( while true; do
    sleep 99999;
done )

スクリプト全体が終了したようです。しかし、私はします ps aux|grep sleep そして、睡眠コマンドがまだ強くなっているのを見つけますが、それ自体のPIDがあります!私は殺すことができます sleep そして、すべてがうまくいくようです。しかし、もし私が最初に睡眠を殺すなら、whileループは新しいものを開始します sleep pid。睡眠はwhileループと平行ではないので、これは私にとって非常に驚きです。ループ自体は、実行の単一のパスです。

だから私には2つの質問があります:

  1. スリープコマンドが独自のプロセスIDを取得したのはなぜですか?
  2. whileループと睡眠を簡単に殺すにはどうすればよいですか?
役に立ちましたか?

解決

  1. 睡眠は独自のものになります PID それは実行されているプロセスであり、ただ待っているからです。試す which sleep それがどこにあるかを見るために。
  2. 使用できます ps -uf システム上のプロセスツリーを表示します。そこから、何を決定することができます PPID 睡眠のシェル(ループを実行しているもの)の(親pid)はです。

他のヒント

やってみましたか kill %1, 、 どこ 1 コマンドをバックグラウンドで起動した後に得られる番号はありますか?

発売後、私は今それをしました (while true;do sleep 99999;done)& そして、それはそれを正しく終了しました。

「PS -PPID」は、指定された親PIDですべてのプロセスを選択します。

$ (while true;do sleep 99999;done)&
[1] 12345

$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)

プロセスグループを殺すことができます。

プロセスのプロセスグループを見つけるには:

ps --no-headers -o "%r" -p 15864

次に、プロセスグループを殺します。

kill -- -[PGID]

すべてを1つのコマンドで行うことができます。試してみましょう:

$ (while true;do sleep 99999;done)&
[1] 16151

$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+  Terminated              ( while true; do
    sleep 99999;
done )
  1. 「睡眠」はプロセスであり、ビルドイン関数や同様のものではないため

  2. 次のことができます。

    (while true;do sleep 99999;done)&
    whilepid=$!
    kill -- -$whilepid
    

上記のコードは、PIDが負の数(123ではなく-123など)として指定されているため、プロセスグループを殺します。さらに、変数を使用します $!, 、最近実行されたプロセスのPIDを保存します。

注:インタラクティブモード(つまり、コマンドラインプロンプトを使用する)でバックグラウンドでプロセスを実行すると、新しいプロセスグループが作成されます。そうすれば、プロセスグループ全体を殺す必要があるため、「すべてを殺す」ことは比較的簡単です。ただし、スクリプト内で同じものが実行される場合、すべての新しいプロセスがバックグラウンドで実行されていても、すべての新しいプロセスがスクリプトPIDに属しているため、新しいグループを作成しません(ジョブコントロールはデフォルトで無効になります)。スクリプトでジョブコントロールを有効にするには、スクリプトの先頭に次のものを配置する必要があります。

#!/bin/bash

set -m

殺すために while ループと sleep 使用 $! aを使用することもできます trap サブシェル内の信号ハンドラー。

(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top