2018-9-17-bash之信號捕捉

1、概述

咱們在上一章當中示例了檢測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腳本自定義如何捕捉信號,但須要注意的是,不能捕捉TERMKILL的信號,由於捕捉信號的意義在於一旦捕捉到以後可以做出什麼操做,所以通常捕捉到信號爲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[@]}

在信號捕捉中的函數內部能夠寫出一些複雜的處理邏輯,包括退出及刪除未處理的文件等。

2、在bash中使用ASCII顏色

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"
相關文章
相關標籤/搜索