pgrep コマンド:名前で PID を探す方法と -f オプション、pidof と pkill の違い
実行中のプロセスの番号(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 コマンドの基本的な使い方
pgrep の後ろに名前の一部を書くと、その文字を含むプロセスの番号を 1 行に 1 つずつ出力します。pgdemo で探すと、pgdemo-a が 2 つと pgdemo-b が 1 つ、合わせて 3 つの番号が出ました。
pgrep pgdemo2143
2152
2155名前を pgdemo-a まで書くと、pgdemo-a の 2 つだけが残りました。
pgrep pgdemo-a2143
2152探す文字は拡張正規表現として読み、オプションがなければプロセス名だけから探します。
探すプロセスがなければ何も出力せずに終わるので、結果は終了コードで確認します。存在しない名前 pgdemo-zz を探した後に [echo $?] を実行すると 1 が出ました。
pgrep pgdemo-zzecho $?1条件を 1 つも書かずに実行すると、下のエラーと一緒に終了コード 2 が出ました。man ページは終了コードを 0(見つかった)、1(見つからない)、2(コマンドラインの文法エラー)、3(メモリ不足などの致命的なエラー)と説明しています。
pgreppgrep: 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 -Vpgrep from procps-ng 4.0.22️⃣ pgrep -f オプションと -l、-a の出力
番号だけではどのプロセスか分からないので、-l で名前を、-a でコマンドライン全体を一緒に出力します。
pgrep -l pgdemo2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-bpgrep -a pgdemo2143 ./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-a2141
2143
2150
2152-a も付けてみると、増えた 2 行は pgdemo-a を引数に受けて実行した timeout でした。名前は timeout ですが、コマンドラインに pgdemo-a が含まれているため -f の条件に合いました。
pgrep -af pgdemo-a2141 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-a2141 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 3013️⃣ pgrep の条件オプション
-x を付けると、名前の一部ではなく名前全体が同じプロセスだけを探します。pgdemo では何も出ず、pgdemo-a で探すと 2 つ出ました。
pgrep -x pgdemopgrep -lx pgdemo-a2143 pgdemo-a
2152 pgdemo-a-u はプロセスを実行したアカウントで絞り込みます。アカウントをカンマで複数書くと、そのどれか 1 つに当てはまるプロセスをすべて探します。root で実行した 3 つのプロセスは [-u root] ですべて出て、[-u daemon] では 1 つも出ませんでした。
pgrep -u root -l pgdemo2143 pgdemo-a
2152 pgdemo-a
2155 pgdemo-bpgrep -u daemon -l pgdemopgrep -u root,daemon -c pgdemo3存在しないアカウントを書くと、[invalid user name] のエラーと一緒に終了コード 2 が出ました。
pgrep -u no-such-user9 pgdemopgrep: invalid user name: no-such-user9Debian 12 サーバーの一般アカウントでも、自分のアカウントで起動した sleep 1 つを同じオプションで見つけました。
pgrep -u user1 -l sleep3047 sleeppgrep -u user1 -a sleep3047 sleep 60同じ名前が複数あるとき、-n は最も最近起動した 1 つ、-o は最も早く起動した 1 つだけを出力します。2 秒間隔で起動した 2 つの pgdemo-a のうち、-n は後のものを、-o は先のものを選びました。
pgrep -n pgdemo-a2152pgrep -o pgdemo-a2143man ページは -n と -o を一緒に使えないと説明しています。両方を書くと、エラーメッセージなしで使い方だけが出ました。
-c は番号の代わりに個数を出力します。見つからなければ 0 を出力し、終了コードは 1 でした。
pgrep -c pgdemo3pgrep -c pgdemo-zz0pgrep のオプションをまとめると次のとおりです。
| オプション | コピー | 説明 |
|---|---|---|
| -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] で減った結果を確認できます。
4️⃣ pgrep と pidof、pkill の違い
pidof は正規表現を使わず、プログラム名全体が同じプロセスだけを探し、番号を 1 行に空白で区切って出力します。pgdemo-a を探すと 2 つの番号が 1 行に出て、後に起動した 2152 が先でした。
pidof pgdemo-a2152 2143名前の一部である pgdemo では、pgrep と違って何も見つからず、終了コードは 1 でした。番号が 1 つだけ必要なら -s を付けます。[pidof -s pgdemo-a] は 2152 を 1 つだけ出力しました。
pidof pgdemopidof -s pgdemo-a2152見つかった番号で開始時刻と親番号(PPID)まで見るには、pgrep -d で番号をカンマでつなぎ、 ps コマンドの -p に渡します。
pgrep -d, pgdemo2143,2152,2155ps -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 301PPID 欄の 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 行に | 探すだけ |
| pkill | pgrep と同じ条件 | なし | 見つかったプロセスにシグナル(既定は SIGTERM) |
🔢 FAQ & おすすめコンテンツ
ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。