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
プロセスには、基本正規表現に一致するコマンドラインも付属しています。
よりカスタマイズされた正規表現を提供すると、プロセス自体のコマンドライン(カスタマイズされた正規表現の転送)が正規表現自体と一致しないため、プロセスは含まれなくなりますpkill
。sudo 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
オプションは導入され、親エントリを無視しますpkill
。pgrep
。
sudo
これは、単に以下を実行してプロセスの終了を回避できることを意味します。
sudo pkill -Aef '/perf record'