「sudo」プロセスを含まずにプロセスを「sudo pkill」するきちんとした方法はありますか?

「sudo」プロセスを含まずにプロセスを「sudo pkill」するきちんとした方法はありますか?

sudoで実行されている一部のプロセスを終了し、フルネームで一致させ、生のコマンド呼び出しの数を数える必要があります。

各プロセスにはコマンド自体とコマンドsudo自体の2つのプロセスがありますが、この問題を解決できます。

$ sudo -b perf record sleep 100

$ pgrep -fa '/perf record'
2245700 /usr/lib/linux-tools/.../perf record sleep 100

問題は、私が呼び出すときに自分自身をsudo pkill見つけて殺して計算することです。

$ sudo pkill -ef '/perf record' | wc -l
2

この場合、pkillに自分自身を含めないようにする簡単な方法はありますか?

私は許可されたpidファイルを試しましたが、pgrep / pkillドキュメントが見つからないため、デフォルトのフォーマットでは機能しないようです。

$ pgrep -f '/perf record' | tee /tmp/pids
$ sudo pkill -F /tmp/pids
 killed (pid 2249211)

最初の人だけが殺されるからです。文書には次のように記載されています。

       -F, --pidfile file
              Read PID's from file.  This option is perhaps more useful for pkill than pgrep.

しかし、その意味はあいまいですPID's

答え1

努力する:

sudo pkill -ef '/[p]erf record' | wc -l

以下は、1文字だけを含む文字クラスを使用するヒントですp

正規表現で を探していますが、/perfコマンドsudo pkillラインにはありますが、/[p]erf一致しません。

このアプローチは、次のコマンドで数十年間使用されてきました。ps aux | awk '/[f]oo/ {print $1}'

答え2

pkill/のパターンは、pgrepのパターンと同じ拡張正規表現ですgrep -E。これにより、必要なプロセスをより正確にターゲットにする正規表現を提供できます。あなたの場合は、次のようになります。

sudo pkill -ef '^(/[^/]+)+/perf record'

またはより良い@casが説明する技術彼の答えに。

なぜこれが必要なのかを説明することをお勧めします。

私たち全員が知っているように、pkill/はpgrep決してそれ自体と一致しません。しかし、彼らが使用する基準は一致するものです。PID、すなわち。一致するPIDの1つが自分のものであることを確認してください。彼らはまさにそれを除外します。

ただし、a(-fすべてのコマンドラインモードオプションを使用)を実行すると、コマンドsudoは独自のプロセスpkillとも一致します。なぜなら、コマンドにはaに一致するコマンドライン文字列も付属しているからです。sudoない使用したものと同じパターンです。明らかに、sudo独自のプロセスはそのプロセスとは異なるPIDを持っているため、pkillそのpkillプロセスはリストから除外されず、sudoそれを作成した(まだ残っている)プロセスを終了しますpkill

考慮する:

$ sudo -b perf record sleep 1234
$ sudo pgrep -fa '/perf record'
1446 /usr/lib/linux-tools/4.2.0-42-generic/perf record sleep 1234
1466 sudo pgrep -fa /perf record  # <-- if I issued a pkill, this process, the sudo, would have been killed

上記のコードスニペットにpgrep注意してください。私自身そのプロセスは実際にはリストから除外されます。ただし、このsudoプロセスには、基本正規表現に一致するコマンドラインも付属しています。

よりカスタマイズされた正規表現を提供すると、プロセス自体のコマンドライン(カスタマイズされた正規表現の転送)が正規表現自体と一致しないため、プロセスは含まれなくなりますpkillsudo pkill -ef <...>


オプションに関する最後の注意事項です-F

この記事を書く今でも、このオプションはまだ存在します。1つのPIDのみを読むファイルから。はい。--helpプログラムの出力だけでなく文書も誤解を招くことがあります。ソースのこのコメント醜い真実です。

/* FreeBSD: arg は含まれていますPIDマッチング*/

答え3

pidを直接インポートして検索しないでください。

pid="$(sudo bash -c 'sleep 100 >/dev/null & echo $!')"
sudo kill "$pid"

バックグラウンドプロセスが何も出力しなくても、stdoutのリダイレクトが必要です。そうしないと、指定された結果に設定され、バックグラウンドジョブがstdoutを閉じるまで子プロセスが読み取ろうとしたときに停止します$()$()

ここで最大の利点pkillは、検索に一致する他のプロセスを潜在的に終了するのではなく、常に正しいpidを取得できることです。たとえば、スクリプトを同時に複数回実行する場合、一致するプロセスがperf複数ある場合があり、[p]erf record各プロセスは各スクリプト呼び出しの子プロセスです。

答え4

今後のprocps 4.0.1ではこの-Aオプションは導入され、親エントリを無視しますpkillpgrep

sudoこれは、単に以下を実行してプロセスの終了を回避できることを意味します。

sudo pkill -Aef '/perf record'

関連情報