Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2867

kill コマンドの使い方まとめ

$
0
0

killコマンドはプロセスの停止や任意のシグナルを送るためのコマンドです。その他、プロセスの生存確認、シグナル一覧出力、シグナル名への変換機能もあります。多くのシェルではビルトインコマンドとして実装されています。(例外は おそらく posh のみ)

この記事では原則として POSIX 準拠の範囲(オプションは -s-l)のみを解説しています。一部の実装では機能が拡張されている場合がありますが省略します。POSIX kill の仕様はこちらを参照してください。

シグナル送信(プロセス停止)

シグナルを送る場合の使い方は以下のとおりです。

$ kill-sシグナル名 PID
$ kill -シグナル名 PID # 上記と同じ$ kill -シグナル番号 PID
$ kill PID # シグナル名を省略すると -TERM(プロセス停止)を指定したのと同じ意味になる

シグナル名は頭に SIGをつけない大文字(例 TERM)で指定します。 POSIX では小文字のシグナル名も許容されるようですが mksh や OpenBSD ksh などで認識されません。後述しますが 0というプロセスの生存確認を行うための特殊なシグナル名(シグナル番号も同じく 0)も使うことができます。

POSIX で動作が保証されているシグナル番号は 0 (0)、1 (SIGHUP)、2 (SIGINT)、3 (SIGQUIT)、6 (SIGABRT)、9 (SIGKILL)、14 (SIGALRM)、15 (SIGTERM) のみです。その他の番号も番号に対応したシグナルとして使えると思いますが、ここに挙げたシグナル番号以外を使った場合の動作は POSIX では保証されていません。また環境によってシグナル番号に対応するシグナルが異なるのでシグナル番号ではなくシグナル名を使用したほうが良いです。

PID には PID(プロセス ID)だけでなくプロセスグループ ID とジョブ ID(バックグラウンドプロセスを作成したときの ID)を指定することができます。PIDとして 0を指定した場合は自分が属するプロセスグループ ID を指定したのと同じ意味になります。PID を -で始めた場合はプロセスグループ ID となり、%で始めた場合はジョブ ID です。

$ kill-sシグナル名 PID # プロセス ID$ kill-sシグナル名 -PGID# プロセスグループ ID$ kill -シグナル番号 %JOBID # ジョブ ID

シグナルよる停止時の終了ステータス

シグナルによってプロセスが停止した場合、プロセスの終了ステータスはシグナルに応じて決まります。POSIX では決まっているのはシグナルで終了した場合の終了ステータスは 128 以上になるということだけのようです。しかしながら(おそらく全ての環境では)シグナル番号に 128 を加えた値が終了ステータスとなります。例えば INT シグナル(シグナル番号 2)で終了した場合の終了ステータスは 130 です。

プロセスの生存確認

シグナル番号(およびシグナル名)0は実際にはシグナルを送りませんがプロセスの存在確認として使用することができます。killコマンドはビルトインコマンドなので他の外部コマンド(psコマンドなど)を使用して確認するよりも高速です。

$ kill-0 1234 # PID 1234 が存在していれば終了ステータスとして 0、存在していなければ 非 0 を返す

シグナル一覧の出力

-lオプションを指定するとシグナル一覧を出力します。出力形式は POSIX で "%s%c", <signal_name>, <separator>と規定されていますが、シェルによってフォーマットが異なるので注意する必要があります。

# bash$ kill-l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
...

# dash$ kill-l
0 # ← 0 が含まれています
HUP
INT
QUIT
...

# ksh$ kill-l
HUP
INT
QUIT
...

# zsh$ kill-l
HUP INT QUIT ILL TRAP ...

# busybox $ busybox kill-l
 1) HUP
 2) INT
 3) QUIT
...

bash の出力は POSIX に準拠していませんが set -o posixで POSIX モードにすると zsh と同様のフォーマットになります。<separator>は改行またはスペースなので縦並びでも横並びでも POSIX 準拠です。シグナルの一覧に 0を含めるかどうかは POSIX には規定されてないようです。

シグナル名への変換

-lオプションの引数として終了ステータスを指定するとシグナル名へ変換することができます。POSIX の仕様では終了ステータスからの変換であってシグナル番号からの変換ではありませんが、おそらく全てのシェルでシグナル番号からでもシグナル名に変換できます。

$ kill-l 130
INT

逆にシグナル名からシグナル番号(または終了ステータス)への変換は POSIX の仕様にはありません。bash, ksh, zsh では -l シグナル名で出来ますが、dash, mksh, yash, posh では出来ません。もしそれが必要な場合はシグナル一覧をパースしたり kill -l シグナル番号から逆変換テーブルを作るとかする必要があるでしょう。

外部コマンドの kill の注意点

ほとんどのシェルでkillはビルトインコマンドとして用意されてるので外部コマンドの killを使用することはあまりないと思いますが、バグや挙動が異なる点があるので注意が必要です。まずジョブ ID が使用できません。ジョブはシェルが管理しているものなので外部コマンドからジョブ ID がわからないためです。killがビルトインでない posh はもともとインタラクティブシェルとしての利用を想定しておらずジョブ制御機能自体が意図的に削除されています。

なお Debian / Ubuntu などでは procps (正確には procps-ng)、RedHat / CentOS などでは util-linux の killコマンドがインストールされています。

procps-ng 版 kill

  • 終了ステータスではなくシグナル番号からシグナル名への変換しかできません。
  • procps-ng 3.3.12 では kill -l 終了ステータス (kill --list 終了ステータス) の書式がバグで機能せずシグナル一覧が出力されてしまいます。期待通りに動作させるには kill -l終了ステータスkill --list=終了ステータスの書式を使用する必要がありますが kill -l終了ステータスの書式は他の実装では動作しません。(このバグは procps-ng 3.3.16では修正されているようです。)
  • procps-ng 3.3.16 kill --versionでバージョン番号が取得できません。kill from procps-ng UNKNOWNと出力されます。

util-linux 版 kill

  • kill -lで出力されるシグナル一覧のリアルタイムシグナルが RT<N> RTMIN+<N> RTMAX-<N>のような表記になっています。

Viewing all articles
Browse latest Browse all 2867

Trending Articles