Linuxでプロセスを確認するには ps aux か top、止めるには kill PID(効かなければ kill -9 PID)を使います。 名前で探すなら pgrep -a 名前、ポートを使っているプロセスなら ss -tlnp で、目的に合ったコマンドを選ぶと一度で答えにたどり着けます。

この記事では、Ubuntu 24.04.4 LTS(procps-ng 4.0.4)で実際に実行した結果を載せながら、目的別の逆引き表、ps の列と STAT 記号の意味、top の画面の読み方、シグナルの使い分け、kill・pkill・killall の違いを解説します。TERM を無視するプロセスを作って KILL で止める例、ゾンビプロセスの扱い、pkill -f が自分のシェルまで一致してしまう例など、試してみてわかったつまずきどころも紹介します。

プロセス確認と停止の逆引き早見表

やりたいこと コマンド
全プロセスを一覧 ps aux / ps -ef
CPU使用率が高い順 ps aux --sort=-%cpu | head
メモリ使用量が多い順 ps aux --sort=-rss | head
名前でPIDを探す pgrep -a nginx
コマンドライン全体で探す pgrep -af "app.py --port"
名前が完全一致するものだけ pgrep -x nginx
親子関係を見る pstree -p PID / ps -ef --forest
子プロセスを探す pgrep -P 親PID
ポートを使っているプロセス ss -tlnp | grep :8080 / lsof -i :8080
ゾンビを探す ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/'
起動時刻・経過時間 ps -o pid,lstart,etime -p PID
スレッド数 ps -o pid,nlwp,cmd -p PID / ps -L -p PID
開いているファイル lsof -p PID / ls -l /proc/PID/fd
リアルタイムで監視 top / top -p PID
1回だけ top の結果を出力 top -b -n1 | head -20
通常の停止(TERM) kill PID
強制停止(KILL) kill -9 PID
名前で停止 pkill -x nginx / killall nginx
一時停止 / 再開 kill -STOP PID / kill -CONT PID
設定の再読み込み kill -HUP PID(対応しているプログラムのみ)
生きているか確認 kill -0 PID && echo alive
優先度を下げる renice -n 10 -p PID
ログアウト後も動かす nohup コマンド > app.log 2>&1 &

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Linuxプロセス確認と停止|ps・top・kill逆引きコマンド一覧」

検証した環境とサンプルプロセス

項目 内容
OS Ubuntu 24.04.4 LTS(コンテナ、カーネル 6.18)
procps-ng(ps / top / pgrep / pkill) 4.0.4
CPU / メモリ 2コア / 約8GB

検証用に、次の4つのプロセスを起動しました。

# CPUを使い続ける(argv[0]を t99-burn に変更)
(exec -a t99-burn python3 burn.py) > /dev/null 2>&1 &
# ポート6991で待ち受けるWebサーバー
(exec -a t99-web python3 -m http.server 6991 --bind 127.0.0.1) > web.log 2>&1 &
# 子を作ってすぐ終了させ、回収しない(ゾンビを作る)
python3 zombie.py &
# スレッド4本+150MBを確保して待つ
python3 threads.py &

zombie.py は次の内容です。

import os, time
pid = os.fork()
if pid == 0:
    os._exit(0)          # 子はすぐ終了
print(f"parent={os.getpid()} child={pid}", flush=True)
time.sleep(600)          # 親は wait() しない

psの列の意味とSTAT記号一覧

主要な列を指定して表示する

ps -o で必要な列だけを並べると、調べたいことが一目でわかります。

ps -o pid,ppid,user,stat,%cpu,%mem,vsz,rss,tty,etime,time,nlwp,cmd -p 6575,6576,6577,6578,6580
  PID  PPID USER     STAT %CPU %MEM    VSZ   RSS TT           ELAPSED     TIME NLWP CMD
 6575     1 root     R    96.2  0.0  18356  7900 ?              00:23 00:00:22    1 t99-burn burn.py
 6576     1 root     S     0.2  0.2  30824 18856 ?              00:23 00:00:00    1 t99-web -m http.server 6991 --bind 127.0.0.1
 6577     1 root     S     0.0  0.0  18352  8140 ?              00:23 00:00:00    1 python3 zombie.py
 6578     1 root     Sl    0.4  1.9 467116 162440 ?             00:23 00:00:00    5 python3 threads.py
 6580  6577 root     Z     0.0  0.0      0     0 ?              00:23 00:00:00    1 [python3] <defunct>
列 意味 読み方のポイント
PID プロセスID kill の対象
PPID 親プロセスのID 1 なら親が先に終わったか、デーモンとして起動
STAT 状態(下の表) R・D・Z に注目
%CPU CPU使用率 起動からの平均。今の値は top で見る
%MEM 物理メモリに占める割合 RSS ÷ 総メモリ
VSZ 仮想メモリサイズ(KiB) 予約しただけの領域も含むので大きく出やすい
RSS 実際に物理メモリにある量(KiB) メモリ使用量はまずRSSを見る
TT 端末 ? は端末なし(デーモン・バックグラウンド)
ELAPSED 起動からの経過時間 etimes で秒数
TIME 消費したCPU時間の累計 6575 は23秒で22秒=ほぼ1コア使い切り
NLWP スレッド数 6578 は本体+4本で5
CMD コマンドライン comm ならプログラム名のみ

threads.py は 150MB を確保したので RSS が約162MB(162440 KiB)になっています。VSZ は 467MB と大きいですが、これはスレッド用スタックなど予約領域を含むためで、メモリ不足の判断には RSS を使います。

STATの記号一覧

記号 状態 説明
R Running 実行中または実行待ち
S Sleeping 割り込み可能な待機(入力待ち・タイマー待ちなど)。大半はこれ
D Disk sleep 割り込み不可の待機(ディスクやNFSのI/O待ち)。KILLも待たされる
T Stopped STOP シグナルや Ctrl+Z で一時停止中
t Tracing stop デバッガで停止中
Z Zombie 終了したが親に回収されていない
I Idle カーネルのアイドルスレッド

STAT の2文字目以降に付く記号です。

記号 意味
< 優先度が高い(nice が負)
N 優先度が低い(nice が正)
s セッションリーダー
l マルチスレッド
+ フォアグラウンドのプロセスグループ

実際に renice -n 10 -p 6575 で優先度を下げると、ps -o pid,ni,cmd の NI 列が 0 から 10 に変わり、STAT に N(優先度が低い)が付きます。

ps aux と ps -ef の違い

形式 由来 特徴
ps aux BSD形式(ハイフンなし) %CPU・%MEM・RSS・STAT が出る。負荷の確認向き
ps -ef UNIX(System V)形式 PPID・開始時刻が出る。親子関係の確認向き
ps -eo 列,列 UNIX形式+列指定 スクリプトで使うならこれ

目的別ワンライナーと実行結果

CPU順・メモリ順に並べる

ps -o pid,stat,cmd --sort=-%cpu -p 6575,6576,6577,6578,6580
ps -o pid,rss,cmd --sort=-rss -p 6575,6576,6577,6578,6580
  PID STAT CMD
 6575 R    t99-burn burn.py
 6578 Sl   python3 threads.py
 6576 S    t99-web -m http.server 6991 --bind 127.0.0.1
 6577 S    python3 zombie.py
 6580 Z    [python3] <defunct>

  PID   RSS CMD
 6578 162440 python3 threads.py
 6576 18856 t99-web -m http.server 6991 --bind 127.0.0.1
 6577  8140 python3 zombie.py
 6575  7900 t99-burn burn.py
 6580     0 [python3] <defunct>

全プロセスから上位を見るときは ps aux --sort=-%cpu | head -6 のように -p を外します。--sort の前の - は降順を表します。

名前で探す(pgrep)

pgrep -f t99-web          # コマンドライン全体から探してPIDだけ
pgrep -l -f t99-burn      # PIDとプロセス名
pgrep -a python3          # PIDとコマンドライン全体
6576
6756
6575 python3
6756 bash

ここで、t99-web を指定したのに 6756 bash も一致しています。 6756 はこのコマンドを実行していたシェル自身で、シェルのコマンドライン文字列に t99-web が含まれていたためです。pgrep は自分自身は除外しますが、呼び出し元のシェルは除外しません。これが pkill -f で問題になる例は後で紹介します。

オプション 照合対象 用途
なし プロセス名(最大15文字)の部分一致 ざっくり探す
-x プロセス名の完全一致 誤一致を避ける
-f コマンドライン全体 引数で区別したいとき
-u ユーザー 実行ユーザーで絞る pgrep -u www-data
-P PPID 親PIDで絞る 子プロセス探し
-n / -o 最新 / 最古の1つ 複数起動しているとき

親子関係を見る(pstree / ps --forest)

pstree -p 6577
pstree -p 6578
python3(6577)---python3(6580)
python3(6578)-+-{python3}(6581)
              |-{python3}(6582)
              |-{python3}(6583)
              `-{python3}(6584)

{} で囲まれているのはスレッドです。ps で木構造を出すには --forest を使います。

ps -f --forest -p $(pgrep -d, -g プロセスグループID)
UID        PID  PPID  C STIME TTY          TIME CMD
root     11151 11150  0 23:40 ?        00:00:00 bash -c sleep 120 & sleep 121 & wait
root     11153 11151  0 23:40 ?        00:00:00  \_ sleep 120
root     11154 11151  0 23:40 ?        00:00:00  \_ sleep 121

全体を見るなら ps -ef --forest | less です。

ポートを使っているプロセスを探す

ss -tlnp | grep 6991
lsof -i :6991
LISTEN 0      5          127.0.0.1:6991       0.0.0.0:*    users:(("python3",pid=6576,fd=3))
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
python3 6576 root    3u  IPv4  14989      0t0  TCP localhost:6991 (LISTEN)

ss -tlnp の -p は root でないと他ユーザーのプロセス名が表示されません。 一般ユーザーなら sudo ss -tlnp とします。ポートの使用中エラー(Address already in use)の詳しい対処は別記事にまとめています。

ゾンビを探す

ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/'
 6580  6577 Z    [python3] <defunct>

ゾンビは PPID(親)を見るのが大切です。 対処はこの後の「止まらないとき」で説明します。

起動時刻・経過時間・スレッド数

ps -o pid,lstart,etime,etimes -p 6575
ps -o pid,nlwp,cmd -p 6578
ps -L -o pid,lwp,stat,cmd -p 6578
  PID                  STARTED     ELAPSED ELAPSED
 6575 Thu Oct  1 23:38:41 2026       00:23      23

  PID NLWP CMD
 6578    5 python3 threads.py

  PID   LWP STAT CMD
 6578  6578 Sl   python3 threads.py
 6578  6581 Sl   python3 threads.py
 6578  6582 Sl   python3 threads.py
 6578  6583 Sl   python3 threads.py
 6578  6584 Sl   python3 threads.py

lstart は起動日時、etime は [[日-]時:]分:秒 形式、etimes は秒数です。「何日も動き続けているプロセス」を探すなら ps -eo pid,etimes,cmd --sort=-etimes | head が便利です。

開いているファイル・/procの情報

ls /proc/6576/fd | wc -l
lsof -p 6576 | head -5
grep -E '^(State|PPid|Threads|VmRSS)' /proc/6578/status
4
State:  S (sleeping)
PPid:   1
VmRSS:    162440 kB
Threads:    5

(lsof -p の出力は、cwd・txt・mem などの種類ごとに開いているファイルが1行ずつ並びます。上では省略しています。)

/proc/PID/ には cmdline・environ・cwd・fd/ などがあり、ps に出ない情報も直接読めます。

topの画面の読み方とキー操作

top -b -n1 は「バッチモードで1回だけ出力」で、ログ保存やスクリプトに使えます。-p でプロセスを絞った結果です。

top -b -n1 -p 6575,6576,6578,6580 | head -20
top - 23:39:18 up 10 min,  0 user,  load average: 1.06, 1.35, 0.82
Tasks:   4 total,   1 running,   2 sleeping,   0 stopped,   1 zombie
%Cpu(s): 52.8 us,  0.0 sy,  0.0 ni, 25.0 id, 22.2 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   8031.1 total,   3851.7 free,   1390.0 used,   3150.1 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   6641.1 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 6575 root      20   0   18356   7900   5016 R 100.0   0.1   0:34.98 python3
 6576 root      20   0   30824  18856   9380 S   0.0   0.2   0:00.05 python3
 6578 root      20   0  467116 162440   5144 S   0.0   2.0   0:00.11 python3
 6580 root      20   0       0      0      0 Z   0.0   0.0   0:00.00 python3

ヘッダー部分

行 項目 読み方
1行目 load average 1分・5分・15分の平均。CPUコア数(この環境は2)を継続的に超えると待ちが発生
2行目 Tasks zombie が増え続けていないか
3行目 us / sy ユーザー空間 / カーネルの CPU 使用率
id アイドル(空き)
wa I/O待ち。高いならディスクを疑う
st 仮想マシンでホストに取られた時間
4行目 buff/cache キャッシュ。必要なら解放されるので「使用中」とは別
5行目 avail Mem 実際に使える目安のメモリ

プロセス部分

列 意味
PR / NI 優先度 / nice 値
VIRT / RES / SHR 仮想 / 物理(ps の RSS 相当)/ 共有メモリ(KiB)
S 状態(ps の STAT と同じ記号)
%CPU 直近の更新間隔での使用率。1コア使い切りで100、2コアなら最大200
TIME+ CPU時間の累計(1/100秒まで)

ps では %CPU が 96.2(起動からの平均)、top では 100.0(直近)と表示されている点が違いです。「今重いのはどれか」は top で見ます。 なお top の COMMAND は既定でプログラム名(comm)のため、exec -a で付けた名前ではなく python3 と表示されています。c キーでコマンドライン表示に切り替わります。

よく使うキー操作

キー 動作
P / M / T CPU順 / メモリ順 / CPU時間順
c コマンドライン全体を表示
1 CPUコアごとに表示
H スレッド単位で表示
u ユーザーで絞り込み
o 条件で絞り込み(例:COMMAND=nginx)
k PIDとシグナルを入力して kill
W 現在の設定を ~/.config/procps/toprc に保存
q 終了

起動オプションでは top -o %MEM(メモリ順)、top -u ユーザー、top -d 5(5秒間隔)がよく使われます。

シグナルの種類と使い分け

kill は「プロセスを終了させるだけのコマンド」ではなく「シグナルを送るコマンド」です。 既定では TERM(15)を送ります。

kill -l で番号と名前の一覧を表示できます。

シグナル 番号 送り方 意味・用途 プロセス側で無視できるか
TERM 15 kill PID 終了の依頼。後片付けしてから終われる できる
INT 2 Ctrl+C / kill -INT 割り込み(端末からの中断) できる
HUP 1 kill -HUP 端末切断。デーモンでは設定の再読み込みに使う慣習 できる
KILL 9 kill -9 即時終了。後片付けなし できない
STOP 19 kill -STOP 一時停止 できない
TSTP 20 Ctrl+Z 端末からの一時停止 できる
CONT 18 kill -CONT / fg / bg 再開 ―
USR1 / USR2 10 / 12 kill -USR1 プログラムごとの独自用途(ログ再オープン等) できる
QUIT 3 Ctrl+\ 終了+コアダンプ できる

止めるときは TERM → 数秒待つ → それでも残れば KILL の順にすると、プログラムが一時ファイルの削除やバッファの書き出しを行う時間を確保できます。

TERMを無視するプロセスをKILLで止める

TERM・HUP・USR1 を受け取ってメッセージを出すだけのプログラムを用意しました。

# ignore_term.py
import signal, time, os
signal.signal(signal.SIGTERM, lambda s, f: print(f"[{os.getpid()}] TERMを受け取りましたが無視します", flush=True))
signal.signal(signal.SIGHUP,  lambda s, f: print(f"[{os.getpid()}] HUPを受け取りました(設定を再読み込みする想定)", flush=True))
signal.signal(signal.SIGUSR1, lambda s, f: print(f"[{os.getpid()}] USR1を受け取りました(ログを再オープンする想定)", flush=True))
print(f"started pid={os.getpid()}", flush=True)
while True:
    time.sleep(1)
python3 -u ignore_term.py > ig.log 2>&1 & IG=$!
kill -HUP $IG; kill -USR1 $IG; kill $IG; sleep 1.5
ps -o pid,stat,cmd -p $IG
kill -STOP $IG; ps -o pid,stat,cmd -p $IG
kill -CONT $IG; ps -o pid,stat,cmd -p $IG
kill -KILL $IG; wait $IG; echo "exit=$?"
cat ig.log
  PID STAT CMD
 6905 S    python3 -u ignore_term.py
  PID STAT CMD
 6905 T    python3 -u ignore_term.py
  PID STAT CMD
 6905 S    python3 -u ignore_term.py
/bin/bash: line 22:  6905 Killed                  python3 -u ignore_term.py > ig.log 2>&1
exit=137
started pid=6905
[6905] HUPを受け取りました(設定を再読み込みする想定)
[6905] USR1を受け取りました(ログを再オープンする想定)
[6905] TERMを受け取りましたが無視します

TERM を送っても状態は S のまま(動き続けている)で、STOP で T、CONT で S に戻り、KILL で終了しました。 KILL はプロセス側で受け取り方を変えられないため、ログに何も残っていません。

終了コードでシグナルを見分ける

シグナルで終了したプロセスの終了コードは「128+シグナル番号」です。検証では TERM で 143、INT(Ctrl+C)で 130、上の KILL で 137 になりました。コンテナやジョブの終了コードが 137 なら KILL(メモリ不足による強制終了のことも多い)、143 なら TERM と判断できます。

kill・pkill・killallの違い

コマンド 指定方法 照合ルール 向いている場面
kill PID ― 対象を確実に1つに絞る
pkill パターン プロセス名(15文字まで)の部分一致、-f でコマンドライン全体 柔軟に指定したい
killall 名前 プロセス名の完全一致 同名のプロセスをまとめて

sleep をコピーした t99nap と、名前が15文字を超える t99-long-process-name を起動して比べました。

./t99nap 300 & ./t99nap 301 & ./t99-long-process-name 302 &
pgrep -l t99na
killall t99na; echo rc=$?
pgrep -a -f "t99nap 301"
pkill -e -f "t99nap 301"
killall -v t99nap
pgrep t99-long-process-name; echo rc=$?
pgrep -l t99-long-proces
killall -v t99-long-process-name; echo rc=$?
8993 t99nap
8994 t99nap
t99na: no process found
rc=1
8994 ./t99nap 301
t99nap killed (pid 8994)
Killed t99nap(8993) with signal 15
pgrep: pattern that searches for process name longer than 15 characters will result in zero matches
Try `pgrep -f' option to match against the complete command line.
rc=1
8995 t99-long-proces
Killed t99-long-process-name(8995) with signal 15
rc=0
結果からわかること 内容
pgrep / pkill は部分一致 t99na で t99nap が見つかる
killall は完全一致 t99na では no process found
-f で引数まで区別できる "t99nap 301" だけを停止
プロセス名は15文字で切れる t99-long-proces と表示され、長い名前の pgrep は0件(警告あり)
killall は長い名前も扱える 実行ファイル名と照合するため一致した

pkill -f が自分のシェルに一致する例

pkill -f は、実行しているシェルのコマンドラインにパターンが含まれていると、そのシェルにも一致します。 検証中、bash -c '... pkill -e -f "t99nap 301" ...' の形で実行したところ、次のように表示されました。

bash killed (pid 7814)
t99nap killed (pid 7822)

対象の t99nap と一緒に、コマンドを実行していた bash も停止しています。ssh 経由や bash -c で実行するときに起こりやすい挙動です。

対策 例
先に pgrep -af で一致するものを確認 pgrep -af "app.py"
名前の完全一致を使う pkill -x t99nap
正規表現で自分の文字列と一致させない pkill -f "[a]pp.py --port 8080"

nohup・&・jobs・fg・bg・disownの使い方

コマンド・操作 動作
コマンド & バックグラウンドで起動
Ctrl+Z フォアグラウンドのジョブを一時停止(TSTP)
jobs -l ジョブ番号とPIDを一覧
fg %1 ジョブ1をフォアグラウンドに戻す
bg %1 停止中のジョブ1をバックグラウンドで再開
kill %1 ジョブ番号で停止
disown %1 ジョブ一覧から外す(ログアウト時に HUP を送らない)
nohup コマンド & HUP を無視する設定で起動

set -m(ジョブ制御を有効化)したスクリプトで実行した結果です。

$ sleep 200 &
$ sleep 300 &
$ jobs -l
[1]-  9232 Running                 sleep 200 &
[2]+  9233 Running                 sleep 300 &
$ kill -STOP %2   # Ctrl+Z と同じ一時停止
$ jobs -l
[1]-  9232 Running                 sleep 200 &
[2]+  9233 Stopped (signal)        sleep 300
$ bg %2
[2]+ sleep 300 &
$ jobs -l
[1]-  9232 Running                 sleep 200 &
[2]+  9233 Running                 sleep 300 &
$ disown %1
$ jobs -l
[2]+  9233 Running                 sleep 300 &

+ はカレントジョブ(fg だけで戻る対象)、- はその次です。disown したジョブは jobs から消えますが、プロセス自体は動き続けます。

nohup で起動したプロセスは、HUP を無視する設定になります。/proc/PID/status の SigIgn(無視しているシグナルのビット)で確認できます。

SigIgn: 0000000000000001    ← nohup sleep(1ビット目=HUPを無視)
SigIgn: 0000000000000000    ← disown しただけの sleep
方法 ログアウト時の HUP 出力先
& のみ 届く → 終了することが多い 端末(閉じると書けない)
& disown シェルから送られない 端末のまま
nohup ... & 無視する 端末なら nohup.out、リダイレクトすればその先
setsid コマンド 別セッションなので届かない 端末のまま
tmux / screen セッションが残る 再接続して確認できる

この検証では標準出力が端末ではなかったため nohup.out は作られませんでした。nohup コマンド > app.log 2>&1 & と出力先を明示する形にすると、どの環境でも同じ動きになります。常駐させるサービスは systemd のユニットにするのがおすすめです。

killしても消えないときの判断フロー

flowchart TD
    A[kill しても消えない] --> B{ps の STAT は?}
    B -->|Z| C[ゾンビ:親PIDを確認]
    C --> C1[親に回収させる / 親を停止する]
    B -->|D| D[I/O待ち:KILLは保留される]
    D --> D1[ディスク・NFS・ストレージを確認]
    B -->|T| E[一時停止中:kill -CONT か fg]
    B -->|S/R| F{PIDが変わっていないか?}
    F -->|変わった| G[親やsystemdが再起動している]
    G --> G1[systemctl stop / 親を先に停止]
    F -->|同じ| H[TERMを無視している → 数秒待って kill -9]

ゾンビ(Z)は親を見る

ゾンビはすでに終了しているので、KILL を送っても変化しません。 親が wait() で回収すると消えます。

$ kill -KILL 6580   # ゾンビ本体に送る
  PID  PPID STAT CMD
 6577     1 S    python3 zombie.py
 6580  6577 Z    [python3] <defunct>
$ kill 6577   # 親を止める
  PID  PPID STAT CMD
 6577     1 Z    [python3] <defunct>
 6580     1 Z    [python3] <defunct>

親を止めると、ゾンビの PPID が 1 に変わりました。通常の Linux では PID 1 の systemd がすぐに回収します。この検証環境はコンテナで、PID 1 は systemd ではなく process_api という別のプログラムだったため、数秒後に回収されて一覧から消えました。

Docker などのコンテナで、アプリ自身が PID 1 になっている場合は、子のゾンビが回収されずに残ることがあります。docker run --init や tini のような小さな init を PID 1 にすると回収されるようになります。

D状態はI/Oの完了を待つ

D(割り込み不可の待機)中のプロセスは、KILL を送っても I/O が終わるまで終了しません。 この記事の環境では D 状態を安定して再現できなかったため実行結果はありませんが、確認は次のコマンドで行えます。

ps -eo pid,stat,wchan:32,cmd | awk '$2 ~ /^D/'
cat /proc/PID/stack     # root のみ。カーネル内でどこを待っているか

wchan には待っているカーネル関数名が表示されます。NFS サーバーの応答待ちやディスクの不調が多いため、dmesg や iostat で I/O の状況を確認します。

親や監視役が再起動している

PID が変わって同じプロセスが出てくる場合は、親(監視役)が再起動しています。 子を起動し直すループを作って試しました。

(while true; do ./t99nap 100; done) &
$ pstree -p 9748
bash(9748)---t99nap(9750)
$ kill 9750
$ pstree -p 9748
bash(9748)---t99nap(9754)

子(9750)を止めると、すぐに新しい子(9754)が起動しました。親の 9748 を止めると、最後の子 9754 は PPID 1 で残ったため、PID を指定して停止しました。

監視役 止め方
systemd systemctl stop サービス名(Restart= が設定されていると kill しても戻る)
シェルのループ・スーパーバイザー 親を先に止め、残った子を止める
プロセスグループごと kill -- -PGID(マイナス付きでグループ全体に送る)
コンテナ docker stop / kubectl delete pod

よくある質問

Q. kill と kill -9 はどう使い分けますか? A. まず kill PID(TERM)で終了を依頼し、数秒待っても残っていれば kill -9 PID(KILL)を使います。KILL はプロセスが後片付けできないため、一時ファイルやロックファイルが残ることがあります。

Q. ps の %CPU と top の %CPU が違うのはなぜですか? A. ps は「起動してからの平均」、top は「直近の更新間隔での値」だからです。今どのプロセスが重いかを知りたいときは top か top -b -n1 を使います。

Q. pkill と killall はどちらを使えばよいですか? A. 名前を正確に指定するなら killall か pkill -x、引数まで含めて区別したいなら pkill -f です。どちらも実行前に pgrep -a(-f なら pgrep -af)で一致するプロセスを確認すると安心です。

Q. ゾンビプロセスは消さないといけませんか? A. ゾンビ自体はメモリをほとんど使いません。数が増え続ける場合は、親プロセスが子を回収していないので、親の再起動や修正で対処します。

まとめ

  • 確認は ps aux(負荷)と ps -ef(親子)、今重いものは top
  • 名前で探すなら pgrep -a、引数まで見るなら pgrep -af、ポートなら ss -tlnp
  • メモリは VSZ ではなく RSS を見る、STAT は R・D・Z に注目
  • 停止は TERM → 待つ → KILL の順、終了コード 137 は KILL、143 は TERM
  • killall は完全一致、pkill は部分一致、pkill -f は自分のシェルにも一致しうる
  • ログアウト後も動かすなら nohup ... > log 2>&1 &、常駐は systemd へ
  • 消えないときは STAT と PPID を見て、ゾンビ・D状態・再起動を見分ける

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Linuxプロセス確認と停止|ps・top・kill逆引きコマンド一覧」

株式会社RJCでは、Linuxのプロセス管理の知識を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?