爲什麼你的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 都有 builtin 的 kill 命令(優先級高,率先命中),相關文檔說明:
-
bash 在 Job Control Builtins
-
zsh 在 Shell-Builtin-Commands,沒有像 bash 那樣分得細。
當你在 bash
和 zsh
中使用 kill
命令時,優先命中的都是 shell 自帶的 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 以上的)。
原始信號定義在這兩個頭文件中 /usr/include/asm/signal.h
和 /usr/include/asm/siginfo.h
1➜ ~ cat /usr/include/linux/signal.h
2/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
3#ifndef _LINUX_SIGNAL_H
4#define _LINUX_SIGNAL_H
5
6#include <asm/signal.h>
7#include <asm/siginfo.h>
8
9#define SS_ONSTACK 1
10#define SS_DISABLE 2
11
12/* bit-flags */
13#define SS_AUTODISARM (1U << 31) /* disable sas during sighandling */
14/* mask for all SS_xxx flags */
15#define SS_FLAG_BITS SS_AUTODISARM
16
17#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 終止(Default action is to terminate the process)
- CONT 18 繼續(與 STOP 相反,fg/bg 命令)
- STOP 19 暫停(同 Ctrl + Z)
KILL
編號 9,好比遊戲裏面的無可奈何、放終極大招了。
CONT/STOP
讀者可以簡單測試下,控制 yes、tail 等命令的輸出,還挺有趣的。
TERM
信號是默認的,通常程序收到該信號後,會觸發相關代碼,做一些收尾動作,然後退出,即所謂的優雅退出。
比如 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 就有所不同,它的優雅關閉是發送 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)
再比如 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
,每次都很感慨,只能說世界是豐富多彩的。
偉人安慰語:
“吾生也有涯,而知也無涯” -- 莊子
版權申明:
- 未標註來源的內容皆為原創,未經授權請勿轉載(因轉載後排版往往錯亂、內容不可控、無法持續更新等);
- 非營利為目的,演繹本博客任何內容,請以'原文出處'或者'參考鏈接'等方式給出本站相關網頁地址(方便讀者)。
相關文章:
- kill
- Linux環境按鍵檢測
- Wayland環境ksnip無法複製問題解決
- Wayland環境下截圖加後期修改
- Wayland 環境下gif錄屏
- Firefox的一些有趣功能
- Ubuntu 切換系統語言
- Firefox 標題欄高度調整
- Wofi使用教程
- 文件共享軟件Dufs推薦