Shell keyword 「trap」

type trap

執行

$ type trap

顯示

trap is a shell builtin

help trap

執行

$ help trap

顯示

trap: trap [-lp] [[arg] signal_spec ...]
    Trap signals and other events.

    Defines and activates handlers to be run when the shell receives signals
    or other conditions.

    ARG is a command to be read and executed when the shell receives the
    signal(s) SIGNAL_SPEC.  If ARG is absent (and a single SIGNAL_SPEC
    is supplied) or `-', each specified signal is reset to its original
    value.  If ARG is the null string each SIGNAL_SPEC is ignored by the
    shell and by the commands it invokes.

    If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell.  If
    a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.  If
    a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a
    script run by the . or source builtins finishes executing.  A SIGNAL_SPEC
    of ERR means to execute ARG each time a command's failure would cause the
    shell to exit when the -e option is enabled.

    If no arguments are supplied, trap prints the list of commands associated
    with each signal.

    Options:
      -l    print a list of signal names and their corresponding numbers
      -p    display the trap commands associated with each SIGNAL_SPEC

    Each SIGNAL_SPEC is either a signal name in <signal.h> or a signal number.
    Signal names are case insensitive and the SIG prefix is optional.  A
    signal may be sent to the shell with "kill -signal $$".

    Exit Status:
    Returns success unless a SIGSPEC is invalid or an invalid option is given.

範例001

執行

$ 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

範例002

執行

$ trap -p

顯示

trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

範例003

signal.sh

#!/usr/bin/env bash


trap "echo got signal!" SIGHUP SIGINT

while true; do

        date;

        sleep 1;

done

設定可執行

$ chmod u+x signal.sh

執行

$ ./signal.sh

另外開啟一個Terminal

找到剛剛執行的pid

執行

$ ps aux | grep signal.sh

或是執行

$ pgrep -f ./signal.sh

可以找到pid,例如

15060

然後對這個process發送signal

執行

$ kill -1 15060

或是執行

$ kill -2 15060

就會在一開始執行 signal.sh 那個 Terminal

看到

got signal!
Tue May 17 20:47:13 CST 20
...略...

上面的的步驟,也可以直接改成執行下面的指令

執行

$ pkill -1 -f ./signal.sh

或是執行

$ pkill -2 -f ./signal.sh

然後執行下面的指令,把剛剛執行的「./signal.sh」關閉

執行

$ pkill -9 -f ./signal.sh

或是執行

$ kill -9 15060

範例004

server.sh

#!/usr/bin/env bash

THE_SIG_HUP=0

handle_signal () {
        if [ $THE_SIG_HUP = 0 ]; then
                THE_SIG_HUP=1;
        else

                THE_SIG_HUP=0;
        fi

}

trap handle_signal SIGHUP

while true; do
        #echo $THE_SIG_HUP;
        if [ $THE_SIG_HUP = 1 ]; then
                echo 'idle';
        else
                date;
        fi

        sleep 1;

done

設定為可執行

$ chmod u+x server.sh

執行

$ ./server.sh

顯示

Tue May 17 20:56:44 CST 2016
Tue May 17 20:56:45 CST 2016
Tue May 17 20:56:46 CST 2016
Tue May 17 20:56:47 CST 2016

然後執行

$ pkill -1 -f ./server.sh

就會顯示

Tue May 17 20:56:48 CST 2016
idle
idle
...略...

然後再執行

$ pkill -1 -f ./server.sh

就會改成

idle
Tue May 17 20:58:30 CST 2016
Tue May 17 20:58:31 CST 2016
Tue May 17 20:58:32 CST 2016
...略...