Advanced shell script to capture the signal of

Capture signal of shell scripts

Advanced shell script to capture the signal of

trap, trap translates to mean, shell scripts in the trap is designed to capture the signal. What signal do? Such as frequently used kill -9, kill -15, CTRL + C belong signal

1, view all available signals

trap -l or to kill -l

[root@linux1 ~]# kill -l
63) SIGRTMAX-1  64) SIGRTMAX    
[root@linux1 ~]# 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
......  

2, common signals are as follows:

Signal     Value     Comment
─────────────────────────────
SIGHUP        1      终止进程,特别是终端退出时,此终端内的进程都将被终止
SIGINT        2      中断进程,几乎等同于sigterm,会尽可能的释放执行clean-up,释放资源,保存状态等(CTRL+C)
SIGQUIT       3      从键盘发出杀死(终止)进程的信号

SIGKILL       9      强制杀死进程,该信号不可被捕捉和忽略,进程收到该信号后不会执行任何clean-up行为,所以资源不会释放,状态不会保存
SIGTERM      15      杀死(终止)进程,几乎等同于sigint信号,会尽可能的释放执行clean-up,释放资源,保存状态等

SIGSTOP      19      该信号是不可被捕捉和忽略的进程停止信息,收到信号后会进入stopped状态
SIGTSTP      20      该信号是可被忽略的进程停止信号(CTRL+Z)

The real signal name is not SIGXXX, but after the removal of the word SIG, each signal as well as the corresponding code

For example, initiating a signal for the process to the PID 12345

kill -1 12345
kill -HUB 12345
kill -SIGHUB 12345

3, trap option

trap -l list the current list of supported signal system, has been used above, the same root kill -l

trap -p equivalent to the trap, the trap has been arranged to view the shell

You can see there are three default shell traps, omit 20,21,22 signal

[root@linux1 ~]# trap
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

4, after doing the signal trapping

  • Ignore signals
  • After capturing the signal corresponding processing. The main is to clean up temporary files created by the script, and then exit.

5, is provided a trap CTRL + C can be ignored and the signal 15

CTRL signal corresponds to the signal corresponding to the SIGINT 15 SIGTERM

[root@linux1 ~]# trap '' SIGINT SIGTERM
[root@linux1 ~]# trap
trap -- '' SIGINT
trap -- '' SIGTERM
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

In this way, the current shell can not be killed by kill -15

6, set a trap to capture the signal -15, print "I caught you anyway ..."

[root@linux1 ~]# trap 'echo "我抓到你啦~"' TERM
[root@linux1 ~]# trap
trap -- '' SIGINT
trap -- 'echo "我抓到你啦~"' SIGTERM
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

Effect, when I launch bash kill -15 signal current is printed out

[root@linux1 ~]# echo $$
8827
[root@linux1 ~]# kill -15 8827
我抓到你啦~
[root@linux1 ~]# kill -15 8827
我抓到你啦~
[root@linux1 ~]# kill -15 8827
我抓到你啦~

7, is provided in a script can ignore a script CTRL + C and CTRL + Z signal

CTRL + C 2 signal, i.e. SIGINT

CTRL + Z signal 20, i.e. SIGTSTP

script:

Script sleeping 10s, then print success, the script ignores signals INT and TSTP

[root@linux1 ~]# cat trap.sh
#!/bin/bash
trap '' SIGINT SIGTSTP
sleep 10
echo success

effect:

<font Color = Red> CTRL + C can not prevent me from sleep </ font>

[root@linux1 ~]# bash trap.sh 
^C^C^Z^Z^C^C^Z^Zccc^Z^Z^Z^C^C^C

success

8, arranged a terminal when the script is able to clean up the garbage and exit the trap script immediately

Script is as follows:

[root@linux1 ~]# cat trap1.sh
#!/bin/bash

trap 'echo trap handing...;rm -rf /tmp/$BASHPID;echo TEMP files cleaned;exit' SIGINT SIGTERM SIGQUIT SIGHUP
mkdir -p /tmp/$$/
touch /tmp/$$/{a..c}.txt
sleep 10
echo first sleep success
sleep 10
echo second sleep success

In this way, the script except SIGKILL signal (kill -9), always clean out temporary garbage

effect

It has been unable to terminate the beginning, and later performed in front of shell found himself under the trap set up a trap to ignore the CTRL + C to exit the shell to re-enter

[root@linux1 ~]# bash trap1.sh 
^Ctrap handing...
TEMP files cleaned

9, trap guardian objects

Trap guard the object is the shell process itself, not the guardian of the child within the shell environment. But if it is to ignore the signal type traps, the entire shell daemon process group will be to ignore the given signal.

[root@linux1 ~]# cat trap2.sh 
#!/bin/bash
trap 'echo trap_handle_time: $(date +"%F %T")' SIGINT SIGTERM
echo time_start: $(date +"%F %T")
sleep 10
echo time_end1: $(date +"%F %T")
sleep 10
echo time_end2: $(date +"%F %T")

#执行脚本后,新开终端使用kill -15杀死它
[root@linux1 ~]# killall -s SIGTERM trap2.sh

#查看输出情况
[root@linux1 ~]# ./trap2.sh 
time_start: 2019-08-27 10:43:48
trap_handle_time: 2019-08-27 10:43:58
time_end1: 2019-08-27 10:43:58
time_end2: 2019-08-27 10:44:08

Can be found, kill executed, the screen does not print trap_handle immediately, but only in 10 runs sleep after printing. sleep guardian of the process have been ignored type trap

As long as a signal is sent to the shell process will wait after the end of the current running process command signal, and then continue to run the script down. (In fact, only when the operation shell script being executed is safe signal system call, the signal can not interrupt the process appear, in various commands in the shell, we can not know directly what the command is system call is executed system call).

But sleep command initiated sleep () call, a signal is safe, so sleep during the execution of the script above, the signal does not directly interrupt their operation, but wait for it to finish after running the command again to perform signal processing.

10, if the shell set a trap for a signal, the shell process receives the signal, <font color = red> will wait for command within a running start before the end of the process traps </ font>

11, CTRL + C and SIGINT not equivalent. When a time pressing CTRL + C, which is transmitted to the entire SIGINT signal set currently running process. Shell script for it, SIGINT not only sent to the shell script process, also sent to the process currently running script

[root@linux1 ~]# cat trap2.sh 
#!/bin/bash
trap 'echo trap_handle_time: $(date +"%F %T")' SIGINT SIGTERM
echo time_start: $(date +"%F %T")
sleep 10
echo time_end1: $(date +"%F %T")
sleep 10
echo time_end2: $(date +"%F %T")

#执行脚本后,立马CTRL+C
[root@linux1 ~]# bash trap2.sh 
time_start: 2019-08-27 10:20:53
^Ctrap_handle_time: 2019-08-27 10:20:54
time_end1: 2019-08-27 10:20:54
time_end2: 2019-08-27 10:21:04

It can be found after the CTRL + C, not only the trap processing, sleep also flew over; CTRL + C illustrate not only the script process receives a SIGINT signal, let the current process receives a SIGINT signal

A bit difficult to understand, come again and look

.jpeg

Guess you like

Origin blog.51cto.com/14012942/2432858