中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

shell腳本中如何進行信號的捕捉

發布時間:2022-01-24 10:21:03 來源:億速云 閱讀:715 作者:柒染 欄目:開發技術

本篇文章給大家分享的是有關shell腳本中如何進行信號的捕捉,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

trap從字面意思看就是就是陷阱的意思但是在shell腳本中trap時專門捕捉kill -9,kill -15,CTRL+C等信號的。

shell腳本中如何進行信號的捕捉

1、查看所有可用的信號

trap -l或kill -l即可

[root@linux1 ~]# kill -l63) SIGRTMAX-1  64) SIGRTMAX    
[root@linux1 ~]# trap -l
 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
......

2、常見的信號如下:

Signal     Value     Comment
─────────────────────────────
SIGHUP        1      終止進程,特別是終端退出時,此終端內的進程都將被終止
SIGINT        2      中斷進程,幾乎等同于sigterm,會盡可能的釋放執行clean-up,釋放資源,保存狀態等(CTRL+C)
SIGQUIT       3      從鍵盤發出殺死(終止)進程的信號

SIGKILL       9      強制殺死進程,該信號不可被捕捉和忽略,進程收到該信號后不會執行任何clean-up行為,所以資源不會釋放,狀態不會保存
SIGTERM      15      殺死(終止)進程,幾乎等同于sigint信號,會盡可能的釋放執行clean-up,釋放資源,保存狀態等

SIGSTOP      19      該信號是不可被捕捉和忽略的進程停止信息,收到信號后會進入stopped狀態
SIGTSTP      20      該信號是可被忽略的進程停止信號(CTRL+Z)

真正的信號名字不是SIGXXX,而是去除SIG后的單詞,每個信號還有對應的代號

比如向PID為12345的進程發起1信號

kill -1 12345kill -HUB 12345kill -SIGHUB 12345

3、trap的選項

trap -l列出當前系統支持的信號列表,上面已經使用過,根kill -l一樣

trap -p等價于trap,查看shell已經布置好的陷阱

可以看到shell默認有三個陷阱,表示忽略20,21,22信號

[root@linux1 ~]# traptrap -- '' SIGTSTPtrap -- '' SIGTTINtrap -- '' SIGTTOU

4、陷阱捕捉到信號后干嘛

  • 忽略信號

  • 捕捉到信號后做相應的處理。主要是清理一些腳本創建的臨時文件,然后退出。

5、設置一個可以忽略CTRL+C和15信號的陷阱

CTRL信號對應的是SIGINT 15信號對應的是SIGTERM

[root@linux1 ~]# trap '' SIGINT SIGTERM[root@linux1 ~]# traptrap -- '' SIGINTtrap -- '' SIGTERMtrap -- '' SIGTSTPtrap -- '' SIGTTINtrap -- '' SIGTTOU

這樣,當前shell就不能被kill -15殺死

6、設置一個陷阱,捕捉到-15信號時,就打印“我抓到你啦~”

[root@linux1 ~]# trap 'echo "我抓到你啦~"' TERM[root@linux1 ~]# traptrap -- '' SIGINTtrap -- 'echo "我抓到你啦~"' SIGTERMtrap -- '' SIGTSTPtrap -- '' SIGTTINtrap -- '' SIGTTOU

效果,當我對當前bash發起kill -15信號時就打印出來了

[root@linux1 ~]# echo $$8827
[root@linux1 ~]# kill -15 8827我抓到你啦~
[root@linux1 ~]# kill -15 8827我抓到你啦~
[root@linux1 ~]# kill -15 8827我抓到你啦~

7、在腳本中設置一個能忽略CTRL+C和CTRL+Z信號的腳本

CTRL+C是2信號,即SIGINT

CTRL+Z是20信號,即SIGTSTP

腳本:

腳本沉睡10s,然后打印success,腳本忽略INT和TSTP信號

[root@linux1 ~]# cat trap.sh#!/bin/bashtrap '' SIGINT SIGTSTP
sleep 10echo success

效果:

CTRL+C也不能阻止我睡覺

[root@linux1 ~]# bash trap.sh ^C^C^Z^Z^C^C^Z^Zccc^Z^Z^Z^C^C^C

success

8、布置一個當腳本被終端時能清理垃圾并立即退出腳本的陷阱

腳本如下:

[root@linux1 ~]# cat trap1.sh#!/bin/bashtrap 'echo trap handing...;rm -rf /tmp/$BASHPID;echo TEMP files cleaned;exit' SIGINT SIGTERM SIGQUIT SIGHUP
mkdir -p /tmp/$$/
touch /tmp/$$/{a..c}.txt
sleep 10echo first sleep success
sleep 10echo second sleep success

這樣,腳本除了SIGKILL信號(kill -9),總能清理掉臨時垃圾

效果

剛開始一直不能終止,后來執行了下trap發現前面shell自己設置了一個忽略CTRL+C的陷阱,退出shell重進即可

[root@linux1 ~]# bash trap1.sh ^Ctrap handing...
TEMP files cleaned

9、陷阱的守護對象

陷阱的守護對象是shell進程本身,不會守護shell環境內的子進程。但如果是信號忽略型陷阱,則會守護整個shell進程組使其忽略給定信號。

[root@linux1 ~]# cat trap2.sh #!/bin/bashtrap 'echo trap_handle_time: $(date +"%F %T")' SIGINT SIGTERMecho time_start: $(date +"%F %T")
sleep 10echo time_end1: $(date +"%F %T")
sleep 10echo time_end2: $(date +"%F %T")#執行腳本后,新開終端使用kill -15殺死它[root@linux1 ~]# killall -s SIGTERM trap2.sh#查看輸出情況[root@linux1 ~]# ./trap2.sh time_start: 2019-08-27 10:43:48
trap_handle_time: 2019-08-27 10:43:58
time_end1: 2019-08-27 10:43:58
time_end2: 2019-08-27 10:44:08

可以發現,kill執行完后,屏幕沒有立即打印trap_handle,而是等sleep 10運行完后才打印的。sleep進程都被忽略型trap守護了

只要是向shell進程發送的信號,都會等待當前正在運行的命令結束后才處理信號,然后繼續腳本向下運行。(實際上,只有當shell腳本中正在執行的操作是信號安全的系統調用時,才會出現信號無法中斷進程的情況,而在shell下的各種命令,我們是沒法直接知道哪些命令中正在執行的系統調用是系統調用的)。

但sleep命令發起的sleep()調用,是一個信號安全的,所以上面腳本中執行sleep的過程中,信號不會直接中斷它們的運行,而是等待它運行完之后再執行信號處理命令。

10、如果shell中針對某信號設置了陷阱,則該shell進程接收到該信號時,會等待其內正在運行的命令結束才開始處理陷阱

11、CTRL+C和SIGINT不是等價的。當某一時刻按下CTRL+C,它是在向整個當前運行的進程組發送SIGINT信號。對shell腳本來說,SIGINT不僅發送給shell腳本進程,還發送給腳本中當前正在運行的進程

[root@linux1 ~]# cat trap2.sh #!/bin/bashtrap 'echo trap_handle_time: $(date +"%F %T")' SIGINT SIGTERMecho time_start: $(date +"%F %T")
sleep 10echo time_end1: $(date +"%F %T")
sleep 10echo time_end2: $(date +"%F %T")#執行腳本后,立馬CTRL+C[root@linux1 ~]# bash trap2.sh time_start: 2019-08-27 10:20:53
^Ctrap_handle_time: 2019-08-27 10:20:54
time_end1: 2019-08-27 10:20:54
time_end2: 2019-08-27 10:21:04

可以發現,CTRL+C后,不僅trap進行處理了,sleep也立馬結束了;說明CTRL+C不僅讓腳本進程收到了SIGINT信號,也讓當前進程收到了SIGINT信號

以上就是shell腳本中如何進行信號的捕捉,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

聂拉木县| 中山市| 佛冈县| 宁晋县| 百色市| 云阳县| 桂阳县| 固阳县| 岚皋县| 炎陵县| 峡江县| 保亭| 临邑县| 浑源县| 鄢陵县| 鄂托克旗| 景洪市| 张家川| 庆阳市| 庆云县| 福贡县| 宣武区| 杨浦区| 东宁县| 阿拉善盟| 永春县| 吴江市| 包头市| 辽宁省| 赣榆县| 玉田县| 玉溪市| 祁东县| 崇明县| 杂多县| 越西县| 九江市| 佛教| 邓州市| 姚安县| 体育|