- Linux
Linux killコマンドの使い方|シグナル一覧とkill -9・pkill
kill は、プロセスに「シグナル」という合図を送るコマンドです。何も指定しなければ SIGTERM(15番、終了のお願い)を送り、kill -9 は SIGKILL(9番、強制終了)を送ります。 名前の印象とは違い、終了させるだけでなく、一時停止・再開・設定の再読み込みなどの合図にも使います。
この記事では、Ubuntu 24.04.4 LTS(bash 5.2.21、procps-ng 4.0.4、psmisc 23.7、coreutils 9.4)で実際に実行した結果をもとに、全シグナルの早見表、kill・pkill・killall・pgrep の違い、SIGTERM から SIGKILL へ進む手順、エラー表示の再現と対処を説明します。既定動作と「捕捉できるか」は、各シグナルを実際にプロセスへ送って確かめました。systemd と macOS に関する部分は手元で動かせなかったため「未実行」と明記しています。
よく使うシグナルとコマンドの早見表
| やりたいこと | コマンド | 送るシグナル | 実行結果で確認した終了コード |
|---|---|---|---|
| ふつうに終了させる(まずこれ) | kill PID |
SIGTERM (15) | 143 |
| 応答がないときの強制終了 | kill -9 PID または kill -KILL PID |
SIGKILL (9) | 137 |
| Ctrl+C と同じ合図を送る | kill -INT PID |
SIGINT (2) | 130 |
| 設定を再読み込みさせる(対応するプログラムのみ) | kill -HUP PID |
SIGHUP (1) | ― |
| 一時停止 / 再開 | kill -STOP PID / kill -CONT PID |
SIGSTOP (19) / SIGCONT (18) | ― |
| 動いているかだけ調べる | kill -0 PID |
送らない(確認のみ) | 0 なら存在 |
| 名前で探す | pgrep -a 名前 |
― | ― |
| 名前で終了させる | pkill -x 名前 / killall 名前 |
SIGTERM (15) | ― |
| 時間制限つきで実行する | timeout 10 コマンド |
SIGTERM (15) | 124 |
| シグナルの一覧を見る | kill -l |
― | ― |
基本の流れは「kill PID → 数秒待つ → まだ動いていれば kill -9 PID」です。 終了コードは「128+シグナル番号」になるため、143 は SIGTERM、137 は SIGKILL で終わったことを表します。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Linux killコマンドの使い方|シグナル一覧とkill -9・pkill」
kill コマンドの基本
書き方
kill PID # SIGTERM を送る(既定)
kill -9 PID # 番号で指定
kill -KILL PID # 名前で指定(SIG は省略できる)
kill -s KILL PID # -s で指定
kill -SIGKILL PID # SIG 付きでもよい
kill PID1 PID2 PID3 # 複数まとめて
PID(プロセスID)は ps や pgrep で調べます。検証では、sleep をコピーして t209worker という名前にしたプログラムを動かして試しました。
./t209worker 300 &
kill $!
wait $!; echo "exit=$?"
実行結果:
exit=143
$! は直前にバックグラウンドで起動したプロセスのPIDです。kill -9 と kill -s INT も同じように試しました。
k.sh: line 4: 7594 Killed ./t209worker 300
exit=137
exit=130
kill はシェルの組み込みコマンドでもある
type -a kill
kill is a shell builtin
kill is /usr/bin/kill
kill is /bin/kill
bash で kill と打つと、bash に組み込まれた kill が使われます。/bin/kill は procps-ng パッケージの別のプログラムで、メッセージの形が少し異なります。ジョブ番号(kill %1)を使えるのは組み込みの kill です。
kill -0 でプロセスの存在を確認する
kill -0 はシグナルを送らず、送れるかどうかだけを調べます。スクリプトで「まだ動いているか」を判定するときに使います。
kill -0 $p; echo "kill -0 exit=$?" # 動いているとき
kill $p; wait $p
kill -0 $p; echo "kill -0 exit=$?" # 終了したあと
実行結果:
kill -0 exit=0
k.sh: line 6: kill: (7596) - No such process
kill -0 exit=1
kill -l の全シグナル一覧
kill -l の実行結果
kill -l
実行結果(bash 5.2.21 の組み込み kill):
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
(38〜63 は SIGRTMIN+4 〜 SIGRTMAX-1。省略)
63) SIGRTMAX-1 64) SIGRTMAX
32番と33番は表示されません(スレッドのライブラリが内部で使うためです)。番号と名前は相互に変換できます。
| コマンド | 実行結果 | 意味 |
|---|---|---|
kill -l 15 |
TERM |
番号から名前へ |
kill -l TERM |
15 |
名前から番号へ |
kill -l 143 |
TERM |
終了コードから名前へ(143 − 128 = 15) |
/bin/kill -L |
1 HUP 2 INT 3 QUIT ... |
表の形で一覧表示 |
番号はCPUの種類によって一部異なるため、スクリプトでは kill -TERM のように名前で書くと読みやすく、移植もしやすくなります(9 と 15 はどの環境でも共通です)。
標準シグナル(1〜31)の早見表
「既定動作」は、プログラムが何も準備していないときにシグナルを受けるとどうなるかです。既定動作と「捕捉できるか」の列は、x86_64 の Ubuntu 24.04 で各シグナルを実際に送って確かめた結果です(既定動作は sleep プロセスに送って終了状態を確認、捕捉は bash の trap で受け取れるかを確認)。コアダンプの有無は、コアファイルの上限を外した状態で調べました。
| 番号 | 名前 | 既定動作 | 捕捉・無視 | 主な用途 |
|---|---|---|---|---|
| 1 | SIGHUP | 終了 | できる | 端末が閉じた合図。サーバーでは設定の再読み込みに使うことが多い |
| 2 | SIGINT | 終了 | できる | Ctrl+C。キーボードからの中断 |
| 3 | SIGQUIT | 終了+コアダンプ | できる | Ctrl+\。調査用の情報を残して終了 |
| 4 | SIGILL | 終了+コアダンプ | できる | 実行できない命令を検出 |
| 5 | SIGTRAP | 終了+コアダンプ | できる | デバッガ用 |
| 6 | SIGABRT | 終了+コアダンプ | できる | プログラム自身による異常終了(abort) |
| 7 | SIGBUS | 終了+コアダンプ | できる | メモリアクセスの異常 |
| 8 | SIGFPE | 終了+コアダンプ | できる | 0で割るなどの演算エラー |
| 9 | SIGKILL | 終了 | できない | 強制終了。最後の手段 |
| 10 | SIGUSR1 | 終了 | できる | プログラムが自由に意味を決められる |
| 11 | SIGSEGV | 終了+コアダンプ | できる | 不正なメモリ参照(Segmentation fault) |
| 12 | SIGUSR2 | 終了 | できる | プログラムが自由に意味を決められる |
| 13 | SIGPIPE | 終了 | できる | 読み手のいないパイプへの書き込み |
| 14 | SIGALRM | 終了 | できる | タイマーの満了 |
| 15 | SIGTERM | 終了 | できる | 終了のお願い。kill の既定 |
| 16 | SIGSTKFLT | 終了 | できる | 現在は使われていない |
| 17 | SIGCHLD | 無視 | できる | 子プロセスが終了・停止した知らせ |
| 18 | SIGCONT | 再開 | できる | 停止中のプロセスを再開 |
| 19 | SIGSTOP | 停止 | できない | 一時停止 |
| 20 | SIGTSTP | 停止(※) | できる | Ctrl+Z。端末からの一時停止 |
| 21 | SIGTTIN | 停止(※) | できる | バックグラウンドから端末を読もうとした |
| 22 | SIGTTOU | 停止(※) | できる | バックグラウンドから端末へ書こうとした |
| 23 | SIGURG | 無視 | できる | ソケットの緊急データ |
| 24 | SIGXCPU | 終了+コアダンプ | できる | CPU時間の上限を超えた |
| 25 | SIGXFSZ | 終了+コアダンプ | できる | ファイルサイズの上限を超えた |
| 26 | SIGVTALRM | 終了 | できる | 仮想タイマーの満了 |
| 27 | SIGPROF | 終了 | できる | プロファイル用タイマーの満了 |
| 28 | SIGWINCH | 無視 | できる | 端末のウィンドウサイズが変わった |
| 29 | SIGIO | 終了 | できる | 入出力が可能になった(/bin/kill -l では POLL と表示) |
| 30 | SIGPWR | 終了 | できる | 電源の異常 |
| 31 | SIGSYS | 終了+コアダンプ | できる | 不正なシステムコール |
| 34〜64 | SIGRTMIN〜SIGRTMAX | 終了 | できる | リアルタイムシグナル。用途はプログラムが決める |
(※)20〜22 は一般に「停止」が既定動作とされています。今回の検証では端末につながっていないプロセスに送ったため停止せず、確実に停止したのは SIGSTOP だけでした。スクリプトから一時停止させたいときは kill -STOP を使うと確実です。
この表でいちばん大事なのは、捕捉も無視もできないシグナルは SIGKILL と SIGSTOP の2つだけという点です(Linux の signal(7) のマニュアルにも、この2つは捕捉・ブロック・無視ができないと書かれています)。それ以外は、プログラムが受け取ったときの動作を自分で決められます。
SIGTERM と SIGKILL の違い
| 項目 | SIGTERM(15) | SIGKILL(9) |
|---|---|---|
| 意味 | 終了のお願い | 強制終了 |
| プログラム側で受け取れるか | 受け取れる(後片付けができる) | 受け取れない |
| 一時ファイルの削除・保存 | プログラムが対応していれば行われる | 行われない |
| 無視されることがあるか | ある | ない |
| 終了コード | 143 | 137 |
| 使う順番 | 最初 | SIGTERM で終わらないとき |
SIGKILL はプログラムに知らされないままカーネルが終了させるため、書きかけのファイルやロックファイルがそのまま残ることがあります。まず SIGTERM を送り、後片付けの時間を待つのが基本です。
SIGTERM → 待機 → SIGKILL の手順
後片付けをするプログラムの例
SIGTERM を受け取ると、ロックファイルを消してから終了するスクリプトです。
graceful.sh:
#!/bin/bash
# SIGTERM を受けたら後片付けをして終わる
cleanup() { echo "[$(date +%T)] SIGTERM を受信。後片付けをして終了します"; rm -f /tmp/t209_graceful.lock; exit 0; }
trap cleanup TERM
touch /tmp/t209_graceful.lock
echo "[$(date +%T)] 起動 PID=$$"
while :; do sleep 0.2; done
段階的に止めるスクリプト(コピペ用)
stop.sh:
#!/bin/bash
# 使い方: ./stop.sh PID [待つ秒数]
pid=$1; wait_sec=${2:-10}
kill -0 "$pid" 2>/dev/null || { echo "PID $pid は見つかりません"; exit 1; }
echo "SIGTERM を送信: PID $pid"
kill -TERM "$pid"
for i in $(seq "$wait_sec"); do
kill -0 "$pid" 2>/dev/null || { echo "${i}秒以内に終了しました"; exit 0; }
sleep 1
done
echo "${wait_sec}秒待っても動いているため SIGKILL を送信"
kill -KILL "$pid"
sleep 0.5
kill -0 "$pid" 2>/dev/null && { echo "まだ残っています(状態を ps で確認)"; exit 2; }
echo "終了しました"
実行結果1:SIGTERM で終了する場合
./graceful.sh &
./stop.sh $! 5
[08:28:57] 起動 PID=7601
SIGTERM を送信: PID 7601
[08:28:58] SIGTERM を受信。後片付けをして終了します
2秒以内に終了しました
終了後にロックファイルが消えていること(ls で No such file or directory)と、終了コードが 0 であることも確かめました。SIGTERM なら、プログラムが用意した後片付けが実行されます。
実行結果2:SIGTERM を無視するプログラムの場合
trap '' TERM で SIGTERM を無視するスクリプト(stubborn.sh)に対して、同じ手順を実行しました。
./stubborn.sh &
kill $!; sleep 1
ps -o pid,stat,cmd -p $!
./stop.sh $! 3
起動 PID=7616
PID STAT CMD
7616 S /bin/bash ./stubborn.sh
SIGTERM を送信: PID 7616
3秒待っても動いているため SIGKILL を送信
終了しました
k.sh: line 8: 7616 Killed ./stubborn.sh
exit=137
kill を送ったあとも ps に残っており、SIGKILL で終了しました。SIGTERM で終わらないことを確かめてから SIGKILL に進む、という順番がこのスクリプトの要点です。待つ秒数は、対象のプログラムが後片付けにかける時間に合わせて決めます。
kill・pkill・killall・pgrep の違い
| コマンド | 指定するもの | 名前の照合 | シグナルの指定 | 対象が見つからないとき | 含まれるパッケージ |
|---|---|---|---|---|---|
kill |
PID(-PGID でグループ、%1 でジョブ) |
― | -9、-KILL、-s KILL |
No such process、終了コード1 |
bash 組み込み / procps |
pgrep |
名前のパターン | 部分一致(正規表現) | 送らない(PIDを表示) | 何も表示せず終了コード1 | procps |
pkill |
名前のパターン | 部分一致(正規表現) | -9、-KILL、--signal KILL |
何も表示せず終了コード1 | procps |
killall |
プロセス名 | 完全一致 | -9、-KILL、-s KILL |
no process found、終了コード1 |
psmisc |
pgrep と pkill は同じ探し方をする兄弟コマンドです。pkill を実行する前に、同じ引数で pgrep を実行すると、どのプロセスが対象になるかを確認できます。
pgrep で対象を確認する
t209worker を3つ起動した状態で試しました。
pgrep -a t209worker
7673 ./t209worker 301
7674 ./t209worker 302
7675 ./t209worker 303
| オプション | 意味 | 実行結果 |
|---|---|---|
pgrep 名前 |
PIDだけを表示 | 7673 7674 7675 |
pgrep -l 名前 |
PIDとプロセス名 | 7673 t209worker ほか |
pgrep -a 名前 |
PIDとコマンドライン全体 | 上の実行結果 |
pgrep -c 名前 |
件数 | 3 |
pgrep -x 名前 |
名前の完全一致 | pgrep -x t209work は0件(終了コード1) |
pgrep -n 名前 / -o |
いちばん新しい / いちばん前からあるもの | 7675 / 7673 |
pgrep -u ユーザー 名前 |
ユーザーで絞る | 3件 |
pgrep -P 親PID |
親プロセスで絞る | 子の3件 |
pgrep -f パターン |
コマンドライン全体と照合 | 次の項を参照 |
pkill -f は思ったより広く一致する
-f を付けると、プロセス名ではなくコマンドライン全体と照合します。引数で区別したいときに便利ですが、同じ文字列を引数に含む別のプロセスにも一致します。コマンドラインに t209worker 302 という文字を含む別の bash を動かして確かめました。
pgrep -af 't209worker 302'
pgrep -af '^./t209worker 302$'
実行結果:
7827 ./t209worker 302
7830 bash -c sleep 3; : t209worker 302 note
7827 ./t209worker 302
1つ目のパターンでは、目的のプロセスに加えて bash も一致しました。^ と $ で前後を固定した2つ目では、目的の1件だけになっています。検証中にも、パターンの文字列を引数に持っていた呼び出し元のシェルが pkill -f の対象になり、一緒に終了する場面がありました。pkill -f の前には pgrep -af で一覧を確認し、パターンはできるだけ具体的にすると安心です。
pkill と killall の実行結果
pkill -e -f '^./t209worker 302$'
killall -v t209worker
t209worker killed (pid 7827)
Killed t209worker(7826) with signal 15
Killed t209worker(7828) with signal 15
pkill -e と killall -v は、シグナルを送った相手を表示するオプションです。対象がいないときは次のようになりました。
pkill -x t209worker; echo "pkill exit=$?"
killall t209worker; echo "killall exit=$?"
pkill exit=1
t209worker: no process found
killall exit=1
| やりたいこと | pkill | killall |
|---|---|---|
| 名前が完全一致するものだけ | pkill -x 名前 |
killall 名前(既定で完全一致) |
| シグナルを指定 | pkill -KILL 名前、pkill --signal KILL 名前 |
killall -KILL 名前、killall -s KILL 名前 |
| 送った相手を表示 | pkill -e 名前 |
killall -v 名前 |
| ユーザーで絞る | pkill -u ユーザー 名前 |
killall -u ユーザー 名前 |
| 正規表現で指定 | 既定で正規表現 | killall -r '正規表現' |
| いちばん新しい1つだけ | pkill -n 名前 |
― |
| 親プロセスで絞る | pkill -P 親PID 名前 |
― |
| 1つずつ確認しながら | ― | killall -i 名前(未実行) |
| 終了するまで待つ | ― | killall -w 名前(未実行) |
「未実行」と書いた2つ以外は、すべて今回の検証で動作を確かめています。
プロセス名は15文字までしか照合されない
Linux が保持するプロセス名(/proc/PID/comm)は15文字までです。20文字の名前のプログラムで試しました。
./t209worker_long_name_x 300 &
cat /proc/$!/comm
pgrep t209worker_long_name_x
pgrep -f t209worker_long_name_x
t209worker_long
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.
7843
16文字以上の名前で pgrep や pkill を使うと0件になり、-f を使うよう案内されます。 killall は長い名前でも Killed t209worker_long_name_x(7843) with signal 15 と表示され、対象を見つけられました。
プロセスグループにまとめて送る
親と子をまとめて終了させたいときは、PIDの代わりに「マイナスを付けたプロセスグループID」を指定します。
ps -o pid,pgid,stat,comm -C t209worker
kill -TERM -- -8432
PID PGID STAT COMMAND
8434 8432 S t209worker
8435 8432 S t209worker
kill -TERM -- -8432
-- は「ここから先はオプションではない」という区切りです。実行後、2つとも終了しました(検証環境では親による回収まで数秒のあいだ Z と表示され、その後一覧から消えました)。
エラー表示の再現と対処
No such process
kill 999999
/bin/kill 999999
実行結果:
k.sh: line 9: kill: (999999) - No such process
/bin/kill: (999999): No such process
指定したPIDのプロセスが存在しないときの表示です。すでに終了しているか、PIDの打ち間違いが考えられます。pgrep -a 名前 や ps -p PID で現在のPIDを確認し直します。 PIDは再利用されるので、時間がたったPIDをそのまま使わず、直前に確認するのが確実です。
Operation not permitted
root が動かしているプロセスに、一般ユーザー taro から kill を実行しました(ユーザー名の表示は置き換えています)。
kill 7656
/bin/kill 7656
pkill -x sleep
実行結果:
bash: line 1: kill: (7656) - Operation not permitted
/bin/kill: (7656): Operation not permitted
pkill: killing pid 7656 failed: Operation not permitted
シグナルを送れるのは、自分が動かしているプロセスか、root の権限があるときだけです。 kill -0 でも同じ表示になるので、権限の確認にも使えます。
| 確認すること | コマンド | 対処 |
|---|---|---|
| プロセスの持ち主 | ps -o pid,user,comm -p PID |
持ち主のユーザーで実行する |
| 管理者として実行してよいか | ― | sudo kill PID |
| サービスとして動いているか | systemctl status サービス名 |
sudo systemctl stop サービス名 |
引数の書き間違い
kill abc
kill -FOO $$
k.sh: line 9: kill: abc: arguments must be process or job IDs
k.sh: line 9: kill: FOO: invalid signal specification
kill にプロセス名は指定できません。名前で指定したいときは pkill か killall を使います。
kill -9 でも消えないゾンビプロセス
ゾンビプロセスは、すでに終了していて、親プロセスが終了状態を受け取る(wait する)のを待っているだけの状態です。ps では Z や <defunct> と表示されます。子がすぐ終了し、親が wait を呼ばないプログラムで再現しました。
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() を呼ばない
python3 zombie.py &
ps -o pid,ppid,stat,comm -p 7664
kill -9 7664; echo "exit=$?"
ps -o pid,ppid,stat,comm -p 7664
実行結果:
parent=7662 child=7664
PID PPID STAT COMMAND
7664 7662 Z python3
exit=0
PID PPID STAT COMMAND
7664 7662 Z python3
kill -9 はエラーにならず終了コード0を返しますが、Z のまま残っています。すでに終了しているプロセスには、シグナルを受け取って動く部分がないためです。
対処は、親プロセス(PPID)に働きかけることです。 親を終了させると、ゾンビは別のプロセス(通常は PID 1 の init や systemd)に引き取られ、そこで回収されて消えます。この流れを、孤児になったプロセスを引き取る役のプログラムを用意して確かめました。
parent=7962 child=7963
PID PPID STAT COMMAND
7963 7962 Z python3
-- kill -9 の後
PID PPID STAT COMMAND
7963 7962 Z python3
-- 親を終了した直後(引き取り先が wait する前)
PID PPID STAT COMMAND
7963 7961 Z python3
-- 引き取り先が wait() で回収: 7963
PID PPID STAT COMMAND
親を終了すると PPID が引き取り先(7961)に変わり、回収されたあとは ps の一覧から消えました(最後は見出し行だけ)。
| 手順 | コマンド |
|---|---|
| 1. ゾンビを探す | ps -eo pid,ppid,stat,comm | awk '$3 ~ /Z/' |
| 2. 親のPIDを調べる | ps -o ppid= -p ゾンビのPID |
| 3. 親が何かを確認する | ps -o pid,user,cmd -p 親のPID |
| 4. 親を通常の手順で終了・再起動する | kill 親のPID(サービスなら systemctl restart) |
ゾンビはメモリやCPUをほとんど使わないので、少数であれば急いで対処する必要はありません。数が増え続けるときは、親プログラムが子の終了を受け取れていない合図なので、親側を見直します。
kill -9 でも終了しないその他の状態
ps の STAT |
状態 | 対処 |
|---|---|---|
Z |
ゾンビ(終了済み) | 親プロセスに対処する |
D |
入出力の完了待ち(割り込めない待機) | ディスクやネットワークストレージの応答を確認する |
T |
停止中 | kill -CONT PID で再開してから終了させる(SIGKILL は停止中でも届く) |
D の状態は今回再現していません(一般に知られた説明です)。
一時停止と再開(SIGSTOP・SIGCONT)
kill -STOP $p; ps -o pid,stat,comm -p $p
kill -CONT $p; ps -o pid,stat,comm -p $p
実行結果:
PID STAT COMMAND
10168 T t209worker
PID STAT COMMAND
10168 S t209worker
STAT が T(停止)になり、kill -CONT で S(待機、通常の状態)に戻りました。重い処理を一時的に止めて、あとで続きから再開したいときに使えます。
終了コードからシグナルを読み取る
シグナルで終了したプロセスの終了コードは、シェルからは「128+シグナル番号」として見えます。ログやスクリプトの $? に見慣れない数字が出たときは、128 を引くとどのシグナルで終わったのかがわかります。今回の検証で確認した値です。
| 終了コード | 意味 | 確認した操作 |
|---|---|---|
| 130 | SIGINT (2) で終了 | kill -s INT PID |
| 137 | SIGKILL (9) で終了 | kill -9 PID、timeout -s KILL |
| 139 | SIGSEGV (11) で終了 | sleep に SIGSEGV を送信 |
| 141 | SIGPIPE (13) で終了 | sleep に SIGPIPE を送信 |
| 143 | SIGTERM (15) で終了 | kill PID |
| 124 | timeout による時間切れ | timeout 1 sleep 10 |
| 127 | コマンドが見つからない | timeout 1 nosuchcmd |
kill -l 137 のように終了コードをそのまま渡すと、bash が KILL と名前に直してくれます。137 を見かけたら「だれか(またはメモリ不足時の仕組み)が SIGKILL を送った」、143 なら「SIGTERM で終了を頼まれた」と読み取れます。
timeout と systemctl kill
timeout で時間制限を付ける
timeout は、指定した時間を過ぎるとコマンドにシグナルを送ります。
| コマンド | 動作 | 終了コード(実行結果) |
|---|---|---|
timeout 1 sleep 10 |
1秒後に SIGTERM | 124 |
timeout -s KILL 1 sleep 10 |
1秒後に SIGKILL | 137 |
timeout -k 1 1 ./stubborn.sh |
1秒後に SIGTERM、さらに1秒後に SIGKILL | 137 |
timeout 5 true |
時間内に終了 | 0(コマンドの終了コード) |
timeout 1 nosuchcmd |
コマンドが見つからない | 127 |
timeout -k 待ち秒数 制限秒数 コマンド は、この記事の「SIGTERM → 待機 → SIGKILL」を1行で書ける形です。SIGTERM を無視する stubborn.sh も、-k を付けることで終了しました。終了コード 124 は「時間切れで止めた」ことを表すので、スクリプトで判定に使えます。
systemctl kill(未実行)
systemd が管理するサービスには、systemctl kill でシグナルを送れます。サービスに属するプロセスをまとめて対象にできるのが特徴です。今回の検証環境は systemd が動いておらず(System has not been booted with systemd as init system と表示)、次の書き方は未実行です。
sudo systemctl kill -s HUP nginx # サービスの全プロセスに SIGHUP
sudo systemctl kill -s TERM --kill-who=main nginx # メインのプロセスだけ
sudo systemctl stop nginx # ふつうに止めるならこちら
サービスを止める目的なら、まず systemctl stop を使います。ユニットに定義された手順で停止し、自動再起動の設定とも整合が取れるためです。
macOS の killall との違い(未実行)
macOS にも kill、pkill、killall がありますが、killall は Linux(psmisc)とは別の実装で、オプションの意味が異なります。macOS は手元で動かせないため、この節は一般に知られた仕様で、未実行です。
| 項目 | Linux(psmisc の killall) | macOS(BSD系の killall) |
|---|---|---|
-s |
シグナルの指定(-s KILL) |
実際には送らず、対象を表示するだけ |
| 正規表現 | -r |
-m |
| シグナルの指定 | -KILL、-s KILL |
-KILL、-SIGKILL |
| ユーザーで絞る | -u ユーザー |
-u ユーザー |
| 確認しながら実行 | -i |
― |
同じ killall -s でも意味が変わるので、両方の環境で使うスクリプトでは pkill -x 名前 や kill -TERM PID のように、差の少ない書き方にそろえると安心です。
安全に止めるためのチェックリスト
| 順番 | 確認すること | コマンド |
|---|---|---|
| 1 | 対象のPIDとコマンドライン | pgrep -a 名前 または ps -fp PID |
| 2 | 持ち主と親プロセス | ps -o pid,ppid,user,stat,cmd -p PID |
| 3 | サービスとして管理されていないか | systemctl status サービス名 |
| 4 | まず SIGTERM | kill PID |
| 5 | 終了したか | kill -0 PID または ps -p PID |
| 6 | 残っていれば SIGKILL | kill -9 PID |
| 7 | 残ったロックファイルや一時ファイル | プログラムの手順に従って片付ける |
よくある質問
Q. kill -9 と kill -KILL、kill -SIGKILL は同じですか?
A. 同じです。どれも SIGKILL を送ります。スクリプトでは、意味が読み取りやすい kill -KILL の形がおすすめです。
Q. Ctrl+C と kill は何が違いますか?
A. Ctrl+C は、端末で手前に動いているプロセスに SIGINT(2番)を送ります。kill PID は SIGTERM(15番)を送ります。どちらもプログラム側で受け取って後片付けができるシグナルです。
Q. kill -HUP で設定が再読み込みされるのはなぜですか? A. SIGHUP を受けたら設定ファイルを読み直す、という動作を各プログラムが自分で用意しているためです。対応していないプログラムでは既定動作どおり終了するので、そのプログラムの説明書で確かめてから使います。
Q. killall と pkill はどちらを使えばよいですか?
A. 名前の完全一致で止めたいなら killall 名前 か pkill -x 名前、引数や親プロセスなど細かい条件で絞りたいなら pkill が向いています。どちらも、先に pgrep -a で対象を確認すると安心です。
まとめ
kill PIDは SIGTERM(15)、kill -9 PIDは SIGKILL(9)を送る。終了コードは 143 と 137- 捕捉も無視もできないのは SIGKILL と SIGSTOP の2つだけ。ほかはプログラムが動作を決められる
- 手順は「SIGTERM → 待つ → SIGKILL」。
timeout -kなら1行で書ける - pkill は部分一致、killall は完全一致。pkill の前に同じ引数の pgrep で対象を確認する
pkill -fはコマンドライン全体と照合するため、^と$でパターンを固定するOperation not permittedは権限、No such processはPIDの確認で対処する- ゾンビは
kill -9では消えない。親プロセスに対処すると回収される
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Linux killコマンドの使い方|シグナル一覧とkill -9・pkill」
株式会社RJCでは、killコマンドとシグナルの使い分けを仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。