shell-trap

shell script如何抓取SIGTERM
即如何抓取外部訊號,讓sciprt不受SIG影響


更新記錄

item note
20160829 第一版

目錄


Unix - Signals and Traps

signal.h

  • signal.h定義下到訊息源
  • cat /usr/include/asm/signal.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #define SIGHUP		 1
    #define SIGINT 2
    #define SIGQUIT 3
    #define SIGILL 4
    #define SIGTRAP 5
    #define SIGABRT 6
    #define SIGIOT 6
    #define SIGBUS 7
    #define SIGFPE 8
    #define SIGKILL 9
    #define SIGUSR1 10
    #define SIGSEGV 11
    #define SIGUSR2 12
    #define SIGPIPE 13
    #define SIGALRM 14
    #define SIGTERM 15
    xx
  • 由kill查訊可以產生訊號如下

  • [root@localhost tt]# kill -l
    1
    2
    3
    4
    5
     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
    xxx

The following are some of the more common signals

Signal Name Signal Number Description
SIGHUP 1 Hang Up detected on controlling terminal or death of controlling process
SIGINT 2 Issued if the user sends an interrupt signal (Ctrl +C).
SIGQUIT 3 Issued if the user sends a quit signal (Ctrl +D).
SIGFPE 8 Issued if an illegal mathmatical operation is attempted
SIGKILL 9 If a process get this signal it must quit immediately and will not perform any clean-up operation
SIGTERM 15 Software termination signal (sent by kill by default)

kill如何產生不同中斷訊息給process

  • [Unix - Signals and Traps][11]
  • The other common method for delivering signals is to use the kill command whose syntax is

    1
    kill -signal pid
  • Sends the HUP or hang-up signal to the program that is running with process ID 1001

    1
    kill -1 1001
  • send a kill signal to the same process use

    1
    kill -9 1001

Trapping Signals

  • [Unix - Signals and Traps][11]
    往往使用script,由於按下Ctrl+C(即SIGINT),未執行完強迫結束
    若想要不受Ctrl+C的影響,則需要用trap command

  • Trapping these signals is quite easy, and the trap command has the following syntax

    1
    trap commands signals
  • 當抓到signals時,則產生command,但此時script shell不會受影響

example-1

  • 使用trap抓取SIGINT訊號,並且打印之後離開程式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@localhost tt]# cat t1.sh 
    #!/bin/bash

    trap "echo TRAP!!;exit" SIGINT
    for ((i=0; i<11; i=i+1))
    do
    echo $i
    sleep 1
    done
  • test

    1
    2
    3
    4
    [root@localhost tt]# ./t1.sh 
    0
    1
    ^CTRAP!!

example-2

  • 使用trap抓取SIGINT訊號,並且打印但不離開程式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@localhost tt]# cat t1.sh 
    #!/bin/bash

    trap "echo TRAP!!;echo CONT." SIGINT
    for ((i=0; i<11; i=i+1))
    do
    echo $i
    sleep 1
    done
  • test

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [root@localhost tt]# ./t1.sh 
    0
    1
    ^CTRAP!!
    CONT.
    2
    3
    ^CTRAP!!
    CONT.
    4
    5
    ^CTRAP!!
    CONT.
    6
    7
    8
    9
    10

pppoe-stop

  • 在pppoe-stop中會發現有使用trap,來防止script未執行完就被中斷離開
    1
    2
    # Ignore SIGTERM
    trap "" 15

如何查檢process是否存在

  • thttpd的PID為2097

    1
    2
    3
    nx        1784  1702  0 Aug30 ?        00:00:01 /usr/NX/bin/nxclient.bin --monitor --pid 1178
    root 2097 1137 0 Aug30 ? 00:00:01 ./thttpd/thttpd -p 80 -C thttpd/thttpd.conf -u root
    root 10603 2 0 00:27 ? 00:00:00 [kworker/3:1]
  • 如何查檢process是否存在
    thttpd的PID為2097
    先使用kill -0 pid檢查此pid是否存在
    若存在則使用kill pid來結束process

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@localhost ~]# kill -0 2097
    [root@localhost ~]# echo $?
    0
    [root@localhost ~]# kill 2097
    [root@localhost ~]# kill -0 2097
    -bash: kill: (2097) - No such process
    [root@localhost ~]# echo $?
    1
    [root@localhost ~]#
  • /usr/sbin/pppoe-stop,使用範例

    1
    2
    3
    4
    5
    6
    7
    # Kill pppoe-start
    PIDS=`cat $STARTPID`
    kill -0 $PIDS > /dev/null 2>&1
    if [ $? = 0 ] ; then
    $LOGGER -p daemon.notice "Killing pppoe-connect"
    kill $PIDS > /dev/null 2>&1
    fi

參考來源