咱們在上一章當中示例了檢測ip地址是否在線的腳本,可是有一個問題,運行的過程當中,不管使用Ctrl+c
怎麼制止,並無什麼卵用,仍是繼續運行,直到將最後一個IP地址ping
完,沒法制止,只是將當前的ping操做結束,下一個ping
操做就要運行,可是若是連續的按下快捷鍵,總有一個信號捕捉到,但只有被當前進程的腳本捕捉到纔可以中止,而不是ping進程,這就是信號。shell
咱們也能夠手動定製信號捕捉的功能,那麼如何自定義信號捕捉的處理,那麼在ping
操做時,因爲信號捕捉不到,那麼能不能在捕捉信號以後作出相應的處理操做,對於bash
而言這是能夠的,在系統當中有一個trap
命令,經過部署一個陷阱捕捉到信號,或者激發其某個事件進行捕捉處理。數組
咱們可以使用-l
選項來列出可捕捉的全部信號。bash
# 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 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
不過,使用kill -l
也是得到相同的結果,不過要想了解其信號意義,咱們可經過man
手冊來進行查看。ide
信號捕捉: 列出信號: trap -l kill -l man 7 signal
信號是進程間通訊間的一種機制,而trap
命令可讓bash
腳本自定義如何捕捉信號,但須要注意的是,不能捕捉TERM
和KILL
的信號,由於捕捉信號的意義在於一旦捕捉到以後可以做出什麼操做,所以通常捕捉到信號爲HUP
以及INT
等,固然其它的信號也能夠捕捉,可是沒有以上這兩個用的那麼頻繁。函數
經常使用的信號: HUP, INT
示例:字體
#!/bin/bash trap 'echo "Dou ni wan"' INT for i in {1..254}; do if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up." else echo "192.168.$i.1 is down." fi done
# bash trap.sh 192.168.1.1 is down. 192.168.2.1 is down. ^CDou ni wan 192.168.3.1 is down. ^CDou ni wan 192.168.4.1 is down. ^CDou ni wan 192.168.5.1 is down. ^CDou ni wan 192.168.6.1 is down.
從以上的運行結果看出,一旦發出Ctrl+c
就是INT
信號後,會顯示出Dou ni wan
,可是其實並無中止其ping
進程,只是中止了當前的ping
,而下一個循環的ping
開始運行,若是完全退出的當前bash進程的話,要用另外一種方式。ui
#!/bin/bash trap 'echo "quit"; exit 1' INT for i in {1..254}; do if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up." else echo "192.168.$i.1 is down." fi done
那麼這就是trap命令的意義,可以其捕捉信號,且捕捉到信號後,使用所定義好的命令來進行處理如何進行,那麼以上的信號處理就是顯示quit並退出shell進程。code
那麼trap命令的方法很簡單,後面跟上其參數,並跟上信號聲明,而一旦捕捉到其信號以後,咱們做出什麼樣的處理操做,而它的命令用法爲:教程
trap 'COMMAND' SIGNALS
咱們可使用以函數中所定義好的命令的形式來對trap
進行定義然後對其進行捕捉。進程
#!/bin/bash # trap 'mytrap' INT mytrap() { echo "Quit" exit 1 } for i in {1..254}; do if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up" else echo "192.168.$i.1 is down" fi done
而在每次ping
操做完成以後,可建立其臨時文件保存其相關的信息。放在循環內部,每一次建立完成可保證將其能夠刪除,也須要保證三叉輸出。
可是這樣的話會建立無數個臨時文件,咱們須要建立其數組用來其追加到最後一個元素中,遇到終止信號時將其文件進行刪除。
#!/bin/bash # declare -a hosttmpfiles trap 'mytrap' INT mytrap() { echo "Quit" rm -f ${hosttmpfiles[@]} exit 1 } for i in {1..254}; do tmpfile=$(mktemp /tmp/ping.XXXXXX) if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up" | tee $tmpfiles else echo "192.168.$i.1 is down" | tee $tmpfiles fi hosttmpfiles[${#hosttmpfiles[*]}]=$tmpfile done echo ${hosttmpfiles[@]}
在信號捕捉中的函數內部能夠寫出一些複雜的處理邏輯,包括退出及刪除未處理的文件等。
在echo
命令中如何進行着色是一件很簡單的事情,關於相關的教程網上也是一抓一大把,那麼其着色定義格式爲:
\033[31m hello \033[0m
以上這種格式表示隨後控制的字體顯示爲何顏色,以及在那裏進行關閉,若是沒有關閉的話隨後都是以這個顏色進行顯示,除非到下一個命令有本身的輸出流時才能結束,爲了不這種影響,因此要在後面需加上\033[0m
,表示不要影響其後面的着色,就在這個範圍內進行着色。
而那兩個數字也有個不一樣的意義。
##m: 左側#: 3: 前景色; 4: 背景色; 右側#: 顏色種類 1, 2, 3, 4, 5, 6, 7
若是使用的是單個數字的話,會改變文本的格式,例如加粗或閃爍等。
#m: 加粗、閃爍等功能; 多種控制符,可組合使用,彼此間用分號隔開;
echo -e "\033[42;35;5,hello world\033[0m"