bash信號捕捉

咱們ping一個主機,而後按下ctrl+c那麼就會終止這個ping動做,以下圖:shell

但是若是使用一個循環來逐個ping不一樣主機,你再按下ctrl+c就會發現停不下來,直到循環完成,以下圖:bash

#!/bin/bash

NETWORK=172.16.42.

# -W 表示超時時長  -c 是發送幾個ping包
for IP in {1..20}; do
  ping -W 1 -c 10 ${NETWORK}${IP}
done

腳本沒有中止而是依然繼續執行,可是你發現172.16.42.1是通的,並且咱們經過-c參數應該是ping 10次,當完成第5次ping的時候,咱們按下ctrl+c它就再也不ping這個地址,而是開始ping 172.16.42.2這個地址。這就是ctrl+c的真正含義,它的做用是終止當前正在執行的操做,腳本中循環20次,每次執行一個ping操做,因此ctrl+c僅僅終止的是其中一個ping操做而不是整個腳本。函數

不過這麼解釋並不徹底正確,由於你要知道ctrl+c是發送中斷信號,究竟是應該終止ping操做仍是這個腳本,取決於捕捉到這個中斷信號的程序,若是是ping捕捉到了,那麼就終止ping操做;若是是執行這個腳本的進程捕捉到就終止這個腳本的執行。那麼咱們如何設置捕捉一個信號呢?就使用trap這個內置的shell命令。ui

trap -l顯示系統信號1kill -l也是能夠顯示的。3d

trap命令不能捕捉SIGKILL和SIGTERM這兩個信號。捕捉信號的目的是一旦信號到達咱們針對信號作什麼處理,若是捕捉SIGKILL而且你修改了行爲,這就意味着這個進程刀槍不入了,這顯然不行。通常咱們捕捉SIGHUP、SIGINT等。code

針對上面的例子如何修改呢?blog

#!/bin/bash

# 捕捉INT,而後執行exit 1,該命令一般寫在腳本第一行
trap 'exit 1' INT

NETWORK=172.16.42.
# -W 表示超時時長 -c 是發送幾個ping包
for IP in {1..20}; do
 ping -W 1 -c 10 ${NETWORK}${IP}
done

再次運行這個腳本那麼依然會執行循環,可是trap並不執行而是一直等着信號發生,咱們使用的ctrl+c其實就是SIGINT信號。這個腳本的含義就是shell捕捉信號,因此shell捕捉到之後就會執行響應動做,咱們這裏是trap 'exit 1' INT捕捉SIGINT而後執行exit 1,當shell執行這個命令時也就意味着退出了,因此不管for循環是否執行完畢它都隨着腳本的退出而終止。進程

若是你想讓捕捉信號時作更多操做,你可使用函數的方式,以下代碼:it

#!/bin/bash

trap 'sig_handler' INT
sig_handler(){
    echo "Quit"
    exit 1
}

NETWORK=172.16.42.
# -W 表示超時時長 -c 是發送幾個ping包
for IP in {1..20}; do
 ping -W 1 -c 10 ${NETWORK}${IP}
done

也就是忽然終止後須要作一些收尾的清理操做,你就能夠經過上面自定義一個函數來執行。io


  1. 信號是進程間通訊的一種方式

相關文章
相關標籤/搜索