防偽碼:李白乘舟將欲行,忽聞岸上踏歌聲。
9.1 Linux 信號類型
信號(Signal):信號是在軟件層次上對中斷機(jī)制的一種模擬,通過給一個(gè)進(jìn)程發(fā)送信號,執(zhí)行響
應(yīng)的處理函數(shù)。
進(jìn)程可以通過三種方式來響應(yīng)一個(gè)信號:
1)忽略信號,即對信號不做任何處理,其中有兩個(gè)信號不能忽略:SIGKILL 及 SIGSTOP。
2)捕捉信號。
3)執(zhí)行缺省操作,Linux 對每種信號都規(guī)定了默認(rèn)操作。
Linux 究竟采用上述三種方式的哪一個(gè)來響應(yīng)信號呢?取決于傳遞給響應(yīng) API 函數(shù)的參數(shù)。
Linux 支持的信號有:
編號 信號名稱 缺省動作 描述
1 SIGHUP 終止 終止進(jìn)程,掛起
2 SIGINT 終止 鍵盤輸入中斷命令,一般是 CTRL+C
3 SIGQUIT CoreDump 鍵盤輸入退出命令,一般是 CTRL+\
4 SIGILL CoreDump 非法指令
5 SIGTRAP CoreDump trap 指令發(fā)出,一般調(diào)試用
6 SIGABRT CoreDump abort(3)發(fā)出的終止信號
7 SIGBUS CoreDump 非法地址
8 SIGFPE CoreDump 浮點(diǎn)數(shù)異常
9 SIGKILL 終止 立即停止進(jìn)程,不能捕獲,不能忽略
10 SIGUSR1 終止
用戶自定義信號 1,像 Nginx 就支持 USR1 信號,用于重載配
置,重新打開日志
11 SIGSEGV CoreDump 無效內(nèi)存引用
12 SIGUSR2 終止 用戶自定義信號 2
13 SIGPIPE 終止 管道不能訪問
14 SIGALRM 終止 時(shí)鐘信號,alrm(2)發(fā)出的終止信號
15 SIGTERM 終止
終止信號,進(jìn)程會先關(guān)閉正在運(yùn)行的任務(wù)或打開的文件再終
止,有時(shí)間進(jìn)程在有運(yùn)行的任務(wù)而忽略此信號。不能捕捉
16 SIGSTKFLT 終止 處理器棧錯(cuò)誤
17 SIGCHLD 可忽略 子進(jìn)程結(jié)束時(shí),父進(jìn)程收到的信號
18 SIGCONT 可忽略 讓終止的進(jìn)程繼續(xù)執(zhí)行
19 SIGSTOP 停止 停止進(jìn)程,不能忽略,不能捕獲
20 SIGSTP 停止 停止進(jìn)程,一般是 CTRL+Z
21 SIGTTIN 停止 后臺進(jìn)程從終端讀數(shù)據(jù)
22 SIGTTOU 停止 后臺進(jìn)程從終端寫數(shù)據(jù)
23 SIGURG 可忽略 緊急數(shù)組是否到達(dá) socket
24 SIGXCPU CoreDump 超出 CPU 占用資源限制
25 SIGXFSZ CoreDump 超出文件大小資源限制
26 SIGVTALRM 終止
虛擬時(shí)鐘信號,類似于 SIGALRM,但計(jì)算的是進(jìn)程占用的時(shí)
間
27 SIGPROF 終止 類似與 SIGALRM,但計(jì)算的是進(jìn)程占用 CPU 的時(shí)間
28 SIGWINCH 可忽略 窗口大小改變發(fā)出的信號
29 SIGIO 終止 文件描述符準(zhǔn)備就緒,可以輸入/輸出操作了
30 SIGPWR 終止 電源失敗
31 SIGSYS CoreDump 非法系統(tǒng)調(diào)用
CoreDump(核心轉(zhuǎn)儲):當(dāng)程序運(yùn)行過程中異常退出時(shí),內(nèi)核把當(dāng)前程序在內(nèi)存狀況存儲在一個(gè)
core 文件中,以便調(diào)試。
Linux 支持兩種信號:
一種是標(biāo)準(zhǔn)信號,編號 1-31,稱為非可靠信號(非實(shí)時(shí)),不支持隊(duì)列,信號可能會丟失,比如發(fā)
送多次相同的信號,進(jìn)程只能收到一次,如果第一個(gè)信號沒有處理完,第二個(gè)信號將會丟棄。
另一種是擴(kuò)展信號,編號 32-64,稱為非可靠信號(實(shí)時(shí)),支持隊(duì)列,發(fā)多少次進(jìn)程就可以收到
多少次。
信號類型比較多,我們只要了解下,記住幾個(gè)常用信號就行了,紅色標(biāo)記的我覺得需要記下。
發(fā)送信號一般有兩種情況:
一種是內(nèi)核檢測到系統(tǒng)事件,比如鍵盤輸入 CTRL+C 會發(fā)送 SIGINT 信號。
另一種是通過系統(tǒng)調(diào)用 kill 命令來向一個(gè)進(jìn)程發(fā)送信號。
l 9.2 kill 命令
kill 命令發(fā)送信號給進(jìn)程。
命令格式:kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l
[sigspec]
-s # 信號名稱
-n # 信號編號
-l # 打印編號 1-31 信號名稱
示例:
給一個(gè)進(jìn)程發(fā)送終止信號:
kill -s SIGTERM pid
或
kill -n 15 pid
或
kill -15 pid
或
kill -TREM pid
p 9.3 trap 命令
trap 命令定義 shell 在處理程序運(yùn)行時(shí)接受信號,來做相應(yīng)的處理。
命令格式:trap [-lp] [[arg] signal_spec ...]
-l # 打印編號 1-64 編號信號名稱
arg # 捕獲信號后執(zhí)行的命令或者函數(shù)
signal_spec # 信號名或編號
一般捕捉信號后,做以下幾個(gè)行動:
1)清除臨時(shí)文件
2)忽略該信號
3)詢問用戶是否終止腳本執(zhí)行
示例 1:按 CTRL+C 不退出循環(huán)
#!/bin/bash
trap "" 2 # 不指定 arg 就不做任何操作,后面也可以寫多個(gè)信號,以空格分隔
for i in {1..10}; do
echo $i
sleep 1
done
# bash a.sh
1
2
3
^C4
5
6
^C7
8
9
10
示例 2:循環(huán)打印數(shù)字,按 CTRL+C 退出,并打印退出提示
#!/bin/bash
trap "echo 'exit...';exit" 2
for i in {1..10}; do
echo $i
sleep 1
done
# bash test.sh
1
2
3
^Cexit...
示例 3:讓用戶選擇是否終止循環(huán)
#!/bin/bash
trap "func" 2
func() {
read -p "Terminate the process? (Y/N): " input
if [ $input == "Y" ]; then
exit
fi
}
for i in {1..10}; do
echo $i
sleep 1
done
# bash a.sh
1
2
3
^CTerminate the process? (Y/N): Y
# bash a.sh
1
2
3
^CTerminate the process? (Y/N): N
4
5
6
...
謝謝觀看,真心的希望能幫到您!
本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!
更多建議: