1つのプロセスがない場合は、1つのプロセスを除いてすべてを終了する方法

1つのプロセスがない場合は、1つのプロセスを除いてすべてを終了する方法

次のスクリプトがあります。

pid = $(ps -ef | grep my-service | awk '{print $2}')

これは私に実行中のプロセスのPIDを与えますmy-service。実行中の複数のプロセスを処理し、my-service最新のプロセスを除くすべての以前のプロセスを終了するようにスクリプトを更新したいと思います。ただし、実行中のプロセスが1つしかない場合は、そのプロセスを終了します。どうすればいいですか?

答え1

pgrep(および)には、プロセス数を計算するための()、最新のPIDのみを取得するための()など、このタスクのいくつかのpkill便利なパラメータがあります。 (詳細)-c--count-n--newestman pgrep

だから私たちはこのcase声明を使うことができます。 pidが返されない場合は終了し、そうであればプロセスを終了します。複数のプロセスが見つかった場合は、grep -v最新のPIDを除くすべてのPIDをターゲットにしてこれをkill

#!/bin/bash

die="my-service"

case $(pgrep -cf "$die") in
    0) exit 0 ;;
    1) pkill -f "$die" ;;
    *) grep -v $(pgrep -nf "$die") <(pgrep -f "$die") | xargs kill ;;
esac

注:-f上記で使用したパラメータは、コマンド全体と一致させるために使用されました。プロセス名のみを一致させるには、このパラメーターを使用しないでください。からman pgrep

-f、--完了

このパターンは通常、プロセス名とのみ一致します。 -fを設定すると、コマンドライン全体が使用されます。

答え2

procps-ngpsと unmodified を仮定すると、$IFS次のことができます。

set -- $(ps -o pid= --sort=-start_time -C my-service)
case $# in
  (0) ;;
  (1) kill "$1";;
  (*) shift; kill "$@"
esac

set分配する位置パラメータ( $1, $2...) を名前付きプロセスの pid に追加し、逆順my-serviceでソートします (最も最近開始されたものから)。start_time

その後、数字($#)を基準にして0であれば何もせず、1であれば殺し、他の数字については最小を捨て、残りは殺しますshift

ps -C name一致するものを参照してください正確に報告された引数のリストではなく、完全なプロセス名にありますps -f

関連情報