killコマンドでシグナルテーブルを一覧できない理由
killコマンドを使って特定のプログラムに特別なシグナルを送りたいけれど、シグナル名や番号がわからない、あるいはスペルミスが心配な場合があります。そんな時は、killコマンドに付属するkill -lコマンドやkill -Lコマンドが役に立つかもしれません。コマンドが役に立つかもしれません。
読者の中には、次のような状況に遭遇する方もいるかもしれません。
1➜ ~ kill -l
2HUP INT QUIT ILL TRAP IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS
3➜ ~ kill -L
4kill: unknown signal: SIGL
5kill: type kill -l for a list of signals
上記の出力をご覧ください。
-
kill -lは数値を含まない単純なリストのみを表示します。 -
kill -Lは実際にはエラーをスローします。
これは、zsh を使用したことが原因である可能性が高いです。
1➜ ~ echo $SHELL
2/usr/bin/zsh
bash に切り替えると、使い慣れたインターフェースに戻ります。
1mephisto@pc:~$ kill -l
2 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
3 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
411) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
516) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
621) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
726) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
831) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
938) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
1043) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
1148) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
1253) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
1358) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
1463) SIGRTMAX-1 64) SIGRTMAX
15mephisto@pc:~$ kill -L
16 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
17 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
1811) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
1916) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
2021) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
2126) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
2231) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
2338) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
2443) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
2548) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
2653) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
2758) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
2863) SIGRTMAX-1 64) SIGRTMAX
なぜこのようなことが起こるのでしょうか?以下の出力をご覧ください(zsh環境)。
1➜ ~ type -a kill
2kill is a shell builtin
3kill is /usr/bin/kill
4kill is /bin/kill
5➜ ~ md5sum /usr/bin/kill /bin/kill
6bec5c7ac875a475f103603d8170dbc31 /usr/bin/kill
7bec5c7ac875a475f103603d8170dbc31 /bin/kill
8➜ ~ echo $SHELL
9/usr/bin/zsh
現在、bash と zsh はどちらも組み込みの kill コマンドを持っています(優先度が高く、最初に実行されます)。関連ドキュメント:
-
bash の ジョブ制御組み込みコマンド
-
zsh の Shell-Builtin-Commands ドキュメント (https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Commands.html#Shell-Builtin-Commands) には、bash のような詳細な区別はありません。
bash と zsh で kill コマンドを使用すると、組み込みの kill コマンドが最初に実行され、その出力の違いが前述の不一致の原因となります。
スタンドアロンの kill コマンドは /bin/kill を使って実行できます (私のマシンでは、/usr/bin/kill は同じ MD5 ハッシュを持つ同じプログラムです)。
1➜ ~ /bin/kill -l
2HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT
3CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS
4➜ ~ /bin/kill -L
5 1 HUP 2 INT 3 QUIT 4 ILL 5 TRAP 6 ABRT 7 BUS
6 8 FPE 9 KILL 10 USR1 11 SEGV 12 USR2 13 PIPE 14 ALRM
715 TERM 16 STKFLT 17 CHLD 18 CONT 19 STOP 20 TSTP 21 TTIN
822 TTOU 23 URG 24 XCPU 25 XFSZ 26 VTALRM 27 PROF 28 WINCH
929 POLL 30 PWR 31 SYS
出力は正常ですが、bash組み込みの数値よりも少なくなっています(31以上少ないです)。
生のシグナル定義は、次の2つのヘッダーファイルにあります: /usr/include/asm/signal.h と /usr/include/asm/siginfo.h
1
2➜ ~ cat /usr/include/linux/signal.h
3
4/* SPDXライセンス識別子: GPL-2.0 WITH Linux-syscall-note */
5
6#ifndef _LINUX_SIGNAL_H
7
8#define _LINUX_SIGNAL_H
9
10#include <asm/signal.h>
11
12#include <asm/siginfo.h>
13
14#define SS_ONSTACK 1
15
16#define SS_DISABLE 2
17
18/* ビットフラグ */
19
20#define SS_AUTODISARM (1U << 31) /* シグナル処理中にSASを無効にする */
21
22/* すべてのSS_xxxフラグのマスク*/
23
24#define SS_FLAG_BITS SS_AUTODISARM
25
26#endif /* _LINUX_SIGNAL_H */
ヘッダーファイルを見てみましょう:
1➜ ~ head -n 62 /usr/include/asm/signal.h
2/_ SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note _/
3#ifndef \_ASM_X86_SIGNAL_H
4#define \_ASM_X86_SIGNAL_H
5
6#ifndef **ASSEMBLY**
7#include <linux/types.h>
8#include <linux/time.h>
9
10/_ Avoid too many header ordering problems. _/
11struct siginfo;
12
13/_ Here we must cater to libcs that poke about in kernel headers. _/
14
15#define NSIG 32
16typedef unsigned long sigset_t;
17
18#endif /_ **ASSEMBLY** _/
19
20#define SIGHUP 1
21#define SIGINT 2
22#define SIGQUIT 3
23#define SIGILL 4
24#define SIGTRAP 5
25#define SIGABRT 6
26#define SIGIOT 6
27#define SIGBUS 7
28#define SIGFPE 8
29#define SIGKILL 9
30#define SIGUSR1 10
31#define SIGSEGV 11
32#define SIGUSR2 12
33#define SIGPIPE 13
34#define SIGALRM 14
35#define SIGTERM 15
36#define SIGSTKFLT 16
37#define SIGCHLD 17
38#define SIGCONT 18
39#define SIGSTOP 19
40#define SIGTSTP 20
41#define SIGTTIN 21
42#define SIGTTOU 22
43#define SIGURG 23
44#define SIGXCPU 24
45#define SIGXFSZ 25
46#define SIGVTALRM 26
47#define SIGPROF 27
48#define SIGWINCH 28
49#define SIGIO 29
50#define SIGPOLL SIGIO
51/_
52#define SIGLOST 29
53_/
54#define SIGPWR 30
55#define SIGSYS 31
56#define SIGUNUSED 31
57
58/_ These should not be considered constants from userland. _/
59#define SIGRTMIN 32
60#define SIGRTMAX \_NSIG
各種シグナルの詳細な説明については、ヘルプドキュメント を参照してください。リアルタイムシグナルに関する情報も含め、非常に包括的な説明が記載されています。
一般的なシグナル:
-
HUP 1 端末のハングアップ
-
INT 2 割り込み(Ctrl + C と同じ)
-
QUIT 3 終了(Ctrl + \ と同じ)
-
KILL 9 強制終了
-
TERM 15 終了(デフォルトの動作はプロセスの終了)
-
CONT 18 継続(STOP、fg/bg コマンドの反対)
-
STOP 19 一時停止(Ctrl + Z と同じ)
9番目の「KILL」は、ゲームにおける「無力感」や「最後の一手」のようなものです。
読者は CONT/STOP を使って yes や tail などのコマンドの出力を簡単に制御できます。これは非常に興味深い機能です。
TERM シグナルがデフォルトです。通常、プログラムがこのシグナルを受信すると、関連するコードがトリガーされ、クリーンアップアクションが実行されてから終了します。このプロセスは graceful exit と呼ばれます。
例えば k8s の場合:
Typically, with this graceful termination of the pod, kubelet makes requests to the container runtime to attempt to stop the containers in the pod by first sending a TERM (aka. SIGTERM) signal, with a grace period timeout, to the main process in each container. The requests to stop the containers are processed by the container runtime asynchronously. There is no guarantee to the order of processing for these requests. Many container runtimes respect the STOPSIGNAL value defined in the container image and, if different, send the container image configured STOPSIGNAL instead of TERM. Once the grace period has expired, the KILL signal is sent to any remaining processes, and the Pod is then deleted from the API Server. If the kubelet or the container runtime's management service is restarted while waiting for processes to terminate, the cluster retries from the start including the full original grace period.
各ソフトウェアはシグナルの処理方法に一貫性がありません。Nginx は異なります。Nginx の正常なシャットダウンは SIGQUIT を送信します 😅:
1nginx -s <SIGNAL>
2
3where <SIGNAL> can be one of the following:
4
5 quit – Shut down gracefully (the SIGQUIT signal)
6 reload – Reload the configuration file (the SIGHUP signal)
7 reopen – Reopen log files (the SIGUSR1 signal)
8 stop – Shut down immediately (or fast shutdown, the SIGTERM singal)
もう 1 つの例は gunicorn です。gunicorn はルーチンに従い、定期的にカードゲームを行います。
1
2Master process
3
4 QUIT, INT: Quick shutdown
5 TERM: Graceful shutdown. Waits for workers to finish their current requests up to the graceful_timeout.
6 HUP: Reload the configuration, start the new worker processes with a new configuration and gracefully shutdown older workers. If the application is not preloaded (using the preload_app option), Gunicorn will also load the new version of it.
7 TTIN: Increment the number of processes by one
8 TTOU: Decrement the number of processes by one
9 USR1: Reopen the log files
10 USR2: Upgrade Gunicorn on the fly. A separate TERM signal should be used to kill the old master process. This signal can also be used to use the new versions of pre-loaded applications. See Upgrading to a new binary on the fly for more information.
11 WINCH: Gracefully shutdown the worker processes when Gunicorn is daemonized.
これは、ソフトウェアのバージョンを表示するために使用する -v、-V、--verson、および -version オプションを思い出させます。それらを見るたびに、世界の多様性と魅力に心を打たれます。
偉人の心温まる言葉:
「人生は有限だが、知識は無限である。」――荘子
著作権に関する声明:
- 出典のないコンテンツはすべてオリジナルです。、無断転載はご遠慮ください(転載後にレイアウトが崩れたり、内容が制御不能になったり、継続的に更新できない等の理由から)。
- このブログのコンテンツを非営利目的で解釈したい場合は、(読者の便宜のため)「オリジナル ソース」または「参照リンク」の形式でこのサイトの関連 Web ページ アドレスを提供してください。
このシリーズの投稿:
- Linux環境のキー検出
- Wayland 環境の ksnip をコピーできない問題が解決されました
- Wayland 環境での GIF 画面録画
- Firefox の興味深い機能
- Wofi 使い方チュートリアル
- Snipe it 資産管理システムのインストールと使用
- Ubuntuの起動を高速化する
- 簡体字中国語の記事を繁体字中国語に一括変換
- Linux 用の Python の最新バージョンをインストールする
- Minetest トライアル