Bash指令碼程式設計學習筆記09:訊號捕捉
阿新 • • 發佈:2020-12-10
簡介
首先我們先來看一段程式碼。
#!/bin/bash declare -i uphosts=0 declare -i downhosts=0 for i in 192.168.152.{98..102}; do if ping -W 2 -c 1 $i &>/dev/null; then echo "$i is up." let uphosts++ else echo "$i is down." let downhosts++ fi done echo "Up hosts is $uphosts, down hosts is $downhosts."
該程式碼針對一個IP地址段進行ping測試,輸出IP地址線上與否並做統計。為了便於觀察效果,我們選擇的IP地址段較短,從192.168.152.98~102,其中只有主機地址為100(即本機)的主機線上。我們執行一遍看結果。
[root@c7-server ~]# bash trap1.sh 192.168.152.98 is down. 192.168.152.99 is down. 192.168.152.100 is up. 192.168.152.101 is down. 192.168.152.102 is down. Up hosts is 1, down hosts is 4.
接下來我們執行第二遍,在執行的過程中,我們使用Ctrl+c嘗試終止指令碼的執行。
[root@c7-server ~]# bash trap1.sh 192.168.152.98 is down. ^C192.168.152.99 is down. 192.168.152.100 is up. 192.168.152.101 is down. ^C192.168.152.102 is down. Up hosts is 1, down hosts is 4.
當98和101主機地址結果顯示出來以後我們立即鍵入Ctrl+c(在上面的輸出結果上我對其進行了加粗標紅),鍵入後99和102的輸出結果立即顯示出來了(由於這是程式碼塊展示,因此無法顯示出動態效果,大家看我描述腦補或者自行實驗)。
我們可以發現Ctrl+c並沒有終止指令碼的執行,而僅僅只是終止了當前迴圈中的ping命令的執行。
如果我們想讓指令碼本身停止,就需要使用bash內建命令trap來捕獲我們對指令碼發出的Ctrl+c命令。
在我之前的一篇部落格中《CentOS 7上的程序管理》已經有談到通過Ctrl+c命令結束正在執行中的指令碼實際上是向指令碼程序發出了SIGINT訊號。
因此我們需要使用trap捕獲SIGINT訊號並對其作出反應(在這裡是嘗試結束指令碼的執行)。
trap語法如下。
trap [-lp] [[arg] signal_spec ...]
arg:當接受到指定的訊號以後將要執行的命令;
signal_spec:具體的訊號;
-l:列出所有的訊號,類似於“kill -l”;
-p:打印出目前已經設定的陷阱,僅鍵入trap命令也有該效果。
[root@c7-server ~]# trap trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU [root@c7-server ~]# trap -p trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU
因此我們只需要在原本的指令碼的頂部(shebang下面)寫入這樣的陷阱即可。
[root@c7-server ~]# cat trap1.sh #!/bin/bash trap "exit" SIGINT declare -i uphosts=0 declare -i downhosts=0 ... ...
結果如下,當指令碼一收到SIGINT訊號,立即結束指令碼,即便迴圈還未停止。
[root@c7-server ~]# bash trap1.sh 192.168.152.98 is down. ^C[root@c7-server ~]# [root@c7-server ~]#
對於訊號捕捉(陷阱)trap的簡單介紹到此為止。