pgrep コマンド:名前で PID を探す方法と -f オプション、pidof と pkill の違い

テスト環境RHEL系AlmaLinux 9.8procps-ng 3.3rootアカウントDebian 12 · procps-ng 4.0.2 一般ユーザー
プロセス・ジョブ予約コマンドpgrep, pidof場所/usr/bin/pgrep

実行中のプロセスの番号(PID)を名前やアカウント、コマンドラインで探すときは pgrep コマンドを使います。AlmaLinux 9 サーバーで sleep プログラムを別の名前でコピーして 3 つ起動し、オプションごとに見つかるプロセスを比べました。名前で探すとその 3 つのプロセスだけが出て、-f でコマンドライン全体から探すと、そのプロセスを起動した timeout まで一緒に出ました。

下の出力は AlmaLinux 9.8 サーバーの root アカウントと Debian 12 サーバーの一般アカウントで実行した結果です。探す対象は sleep を pgdemo-a、pgdemo-b という名前でコピーし、timeout 300 で起動したプロセスで、5 分後に自分で終わるようにしました。プロセス番号(PID)と Debian のアカウント名(user1)は例の値に置き換え、AlmaLinux サーバーの procps-ng のバージョン番号はメジャー・マイナーまでにしました。

1️⃣ pgrep コマンドの基本的な使い方

  • ↪️ 名前で PID を探す方法と終了コード

pgrep の後ろに名前の一部を書くと、その文字を含むプロセスの番号を 1 行に 1 つずつ出力します。pgdemo で探すと、pgdemo-a が 2 つと pgdemo-b が 1 つ、合わせて 3 つの番号が出ました。

pgrep pgdemo
2143
2152
2155

名前を pgdemo-a まで書くと、pgdemo-a の 2 つだけが残りました。

pgrep pgdemo-a
2143
2152

探す文字は拡張正規表現として読み、オプションがなければプロセス名だけから探します。

探すプロセスがなければ何も出力せずに終わるので、結果は終了コードで確認します。存在しない名前 pgdemo-zz を探した後に [echo $?] を実行すると 1 が出ました。

pgrep pgdemo-zz
echo $?
1

条件を 1 つも書かずに実行すると、下のエラーと一緒に終了コード 2 が出ました。man ページは終了コードを 0(見つかった)、1(見つからない)、2(コマンドラインの文法エラー)、3(メモリ不足などの致命的なエラー)と説明しています。

pgrep
pgrep: no matching criteria specified
Try `pgrep --help' for more information.
echo $?
2

出力の代わりにこの終了コードを条件にすれば、スクリプトでプロセスが実行中かどうかを確認できます。バージョンは [pgrep -V] で確認します。Debian 12 サーバーは procps-ng 4.0.2、AlmaLinux 9.8 サーバーは procps-ng 3.3 でした。

pgrep -V
pgrep from procps-ng 4.0.2

2️⃣ pgrep -f オプションと -l、-a の出力

  • ↪️ コマンドライン全体から探すと一緒に出るプロセス

番号だけではどのプロセスか分からないので、-l で名前を、-a でコマンドライン全体を一緒に出力します。

pgrep -l pgdemo
2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-b
pgrep -a pgdemo
2143 ./pgdemo-a 300
2152 ./pgdemo-a 301
2155 ./pgdemo-b 300

-a の出力の最後にある 300 と 301 は、sleep に渡した秒単位の引数です。名前が同じ 2 つの pgdemo-a をこの引数で区別しました。

-f を付けると、名前ではなくコマンドライン全体から探します。pgdemo-a を -f で探すと、番号が 2 つから 4 つに増えました。

pgrep -f pgdemo-a
2141
2143
2150
2152

-a も付けてみると、増えた 2 行は pgdemo-a を引数に受けて実行した timeout でした。名前は timeout ですが、コマンドラインに pgdemo-a が含まれているため -f の条件に合いました。

pgrep -af pgdemo-a
2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301

スクリプトの中で -f を使うときは、スクリプト自身も結果に出ないか確認します。pgrep は実行中の自分自身を結果に入れませんが、pgrep を実行したスクリプトのコマンドラインに探す文字があれば、そのスクリプトも結果に出ます。

受け取った文字をそのまま [pgrep -af] に渡すスクリプト chk.sh で pgdemo-a を探すと、最後の行にスクリプト自身である bash chk.sh pgdemo-a が加わりました。

bash chk.sh pgdemo-a
2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301
2160 bash chk.sh pgdemo-a

パターンの最初の文字を角かっこで囲んだ [p]gdemo-a は、正規表現としては pgdemo-a と同じ文字を探しますが、スクリプトのコマンドラインには角かっこまでそのまま書かれているので条件に合いません。同じスクリプトにこのパターンを渡すと、スクリプトの行が消えて 4 行だけが残りました。

bash chk.sh '[p]gdemo-a'
2141 timeout 300 ./pgdemo-a 300
2143 ./pgdemo-a 300
2150 timeout 300 ./pgdemo-a 301
2152 ./pgdemo-a 301

3️⃣ pgrep の条件オプション

  • ↪️ -u アカウント、-x 完全な名前、-n と -o、-c 個数

-x を付けると、名前の一部ではなく名前全体が同じプロセスだけを探します。pgdemo では何も出ず、pgdemo-a で探すと 2 つ出ました。

pgrep -x pgdemo
pgrep -lx pgdemo-a
2143 pgdemo-a
2152 pgdemo-a

-u はプロセスを実行したアカウントで絞り込みます。アカウントをカンマで複数書くと、そのどれか 1 つに当てはまるプロセスをすべて探します。root で実行した 3 つのプロセスは [-u root] ですべて出て、[-u daemon] では 1 つも出ませんでした。

pgrep -u root -l pgdemo
2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-b
pgrep -u daemon -l pgdemo
pgrep -u root,daemon -c pgdemo
3

存在しないアカウントを書くと、[invalid user name] のエラーと一緒に終了コード 2 が出ました。

pgrep -u no-such-user9 pgdemo
pgrep: invalid user name: no-such-user9

Debian 12 サーバーの一般アカウントでも、自分のアカウントで起動した sleep 1 つを同じオプションで見つけました。

pgrep -u user1 -l sleep
3047 sleep
pgrep -u user1 -a sleep
3047 sleep 60

同じ名前が複数あるとき、-n は最も最近起動した 1 つ、-o は最も早く起動した 1 つだけを出力します。2 秒間隔で起動した 2 つの pgdemo-a のうち、-n は後のものを、-o は先のものを選びました。

pgrep -n pgdemo-a
2152
pgrep -o pgdemo-a
2143

man ページは -n と -o を一緒に使えないと説明しています。両方を書くと、エラーメッセージなしで使い方だけが出ました。

-c は番号の代わりに個数を出力します。見つからなければ 0 を出力し、終了コードは 1 でした。

pgrep -c pgdemo
3
pgrep -c pgdemo-zz
0

pgrep のオプションをまとめると次のとおりです。

オプションコピー説明
-f--full名前ではなくコマンドライン全体から探す
-l--list-name番号と一緒に名前を出力
-a--list-full番号と一緒にコマンドライン全体を出力
-x--exact名前全体が同じプロセスだけを探す
-u--euid指定したアカウントが実行したプロセスだけ、カンマで複数書くとそのどれか
-n--newest条件に合うもののうち最も最近起動した 1 つ
-o--oldest条件に合うもののうち最も早く起動した 1 つ
-c--count番号の代わりに個数を出力、0 個なら終了コード 1
-d--delimiter番号の間の区切り文字を指定(既定は改行)
-V--versionバージョンを出力
オプションコピー説明
-i--ignore-case大文字と小文字を区別せずに探す
-v--inverse条件に合わないプロセスを探す
-P--parent指定した親番号(PPID)の子プロセスだけ
-t--terminal指定した端末につながったプロセスだけ
-g--pgroup指定したプロセスグループ番号に属するプロセスだけ
-s--session指定したセッション番号に属するプロセスだけ
-U--uid実ユーザー ID が同じプロセスだけ
-G--group実グループ ID が同じプロセスだけ
-w--lightweightプロセス番号の代わりにスレッド番号をすべて出力

🔲 pgrep コマンドシミュレーター

下のシミュレーターは、pgdemo と timeout の 6 行に例のプロセスを加えた一覧から始まります。チップを押してオプションごとに見つかった行を左の一覧で比べ、[pkill pgdemo-b] の後に [pgrep -l pgdemo] で減った結果を確認できます。

pgrep コマンドシミュレーターprocps-ng 3.3
[root@server work]#
ブラウザーの中だけで動きます。左の一覧は例の値で、pgrep で見つかった行の横に [今見つかったプロセス] が付きます。[pkill] は一覧から消すだけの再現です。

4️⃣ pgrep と pidof、pkill の違い

  • ↪️ 名前どおりに探す pidof とシグナルを送る pkill

pidof は正規表現を使わず、プログラム名全体が同じプロセスだけを探し、番号を 1 行に空白で区切って出力します。pgdemo-a を探すと 2 つの番号が 1 行に出て、後に起動した 2152 が先でした。

pidof pgdemo-a
2152 2143

名前の一部である pgdemo では、pgrep と違って何も見つからず、終了コードは 1 でした。番号が 1 つだけ必要なら -s を付けます。[pidof -s pgdemo-a] は 2152 を 1 つだけ出力しました。

pidof pgdemo
pidof -s pgdemo-a
2152

見つかった番号で開始時刻と親番号(PPID)まで見るには、pgrep -d で番号をカンマでつなぎ、 ps コマンドの -p に渡します。

pgrep -d, pgdemo
2143,2152,2155
ps -fp $(pgrep -d, -x pgdemo-a)
UID          PID    PPID  C STIME TTY          TIME CMD
root        2143    2141  0 15:59 ?        00:00:00 ./pgdemo-a 300
root        2152    2150  0 15:59 ?        00:00:00 ./pgdemo-a 301

PPID 欄の 2141 と 2150 は、2 つの pgdemo-a を実行した timeout の番号です。

pkill は pgrep と同じ条件でプロセスを探しますが、番号を出力する代わりにシグナルを送ります。シグナルを書かなければ SIGTERM を送り、[pkill -HUP 名前] のようにシグナルを変えられます。

pkill は見つけるとすぐにシグナルを送るので、同じ条件の [pgrep -a] や [pgrep -af] で対象を先に確認します。-f で探すと、コマンドラインに同じ文字を含む timeout やスクリプトも対象に入ります。番号がすでに分かっているなら、 kill コマンドでその番号にだけシグナルを送ります。

コマンド探す基準出力作業
pgrep名前の一部(正規表現)・-f ならコマンドライン全体番号・-l、-a で名前とコマンドライン探すだけ
pidofプログラム名全体番号を 1 行に探すだけ
pkillpgrep と同じ条件なし見つかったプロセスにシグナル(既定は SIGTERM)

🔢 FAQ & おすすめコンテンツ

pgrep はプロセス名を /proc/PID/stat に残る 15 文字までしか比べません。名前が 15 文字より長ければ先頭の 15 文字で探すか、-f で /proc/PID/cmdline のコマンドライン全体から探します。

ps の一覧を grep で絞り込むと、その grep のコマンドラインにも探す名前が含まれているため、結果に一緒に出ることがあります。pgrep は実行中の自分自身を結果に入れず、番号だけを出力するので、ほかのコマンドに渡しやすいです。

-v を付けると条件を反転し、合わないプロセスを探します。pkill では誤操作を防ぐため、短いオプション -v を使えません。

ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

人間であることを証明してください: 10   +   6   =