trap是Linux的內建命令,它用於捕捉信號,trap命令可以指定收到某種信號時所
執行的命令,比如,trap可以指定收到由ctrl+c組合鍵所觸發的INT信號時,執行
中斷處理命令,trap的格式如下:
trap command sig1 sig2... sigN
vi traploop.sh
#!/bin/bash
#一旦收到INT信號,執行雙引號內的echo命令
trap "echo 'You hit CONTROL+C'" INT
while :; do #使用冒號表示永真,無限循環
let count=count+1
echo "This is the $count sleep"
sleep 5
done
./traploop.sh
This is the 1 sleep
This is the 2 sleep
This is the 3 sleep
^CYou hit CONTROL+C
This is the 4 sleep
This is the 5 sleep
^CYou hit CONTROL+C
This is the 6 sleep
vi nokillme.sh
#!/bin/bash
trap "" TERM INT #忽略對TERM和INT兩種信號的處理
#如果還要忽略其它信號,將它們添加到INT之后
#無限循環,每次進入循環體都休眠5s
while :; do
sleep 5
done
chmod u+x nokillme.sh
./nokillme.sh &
[1] 46532
kill %1 #試圖殺死nokillme.sh進程
jobs #nokillme.sh進程仍在運行
[1]+ Running ./nokillme.sh &
kill -9 %1
[1]+ Killed ./nokillme.sh
jobs
當我們用kill %1命令殺死1號作業,由於kill命令發送的是TERM信號,
nokillme.sh腳本的trap命令忽略了對TERM信號的處理,因此kill %1
命令不能殺死nokillme.sh進程。
kill -9 %1,向任務1發送9號信號(kill),等價於kill -KILL %1
子shell能繼父Shell所忽略的信號,但是,不能繼成父Shell未忽略的信號。
vi forever.sh
#!/bin/bash
while :; do
sleep 5
done
vi subsig.sh
#!/bin/bash
trap "" QUIT #忽略QUIT信號
trap "echo 'You want to kill me'" TERM #捕捉到TERM信號,打印提示信息
( #將forever.sh腳本作為子Shell,子shell將無限休眠
./forever.sh
)
./subsig.sh & #運行subsing.sh
[1] 46590 #返回父進程的作業
kill -3 1876
bash: kill: (1876) - No such process
kill -3 46590 #向父進程發送3號信號,即QUIT信號
ps -a
PID TTY TIME CMD
24345 pts/19 00:00:00 telnet
44710 pts/17 00:00:00 sudo
44746 pts/17 00:00:00 sudo
44747 pts/17 00:00:00 sort
44748 pts/17 00:00:00 sudo
44749 pts/17 00:00:00 sort
44750 pts/17 00:00:00 sudo
44751 pts/17 00:00:00 sort
44759 pts/17 00:00:00 su
44760 pts/17 00:00:00 bash
45497 pts/17 00:00:00 vi
45498 pts/17 00:00:00 vi
46590 pts/17 00:00:00 subsig.sh #父進程未退出,說明QUIT信號被忽略
46591 pts/17 00:00:00 forever.sh
46599 pts/17 00:00:00 sleep
46600 pts/17 00:00:00 ps
kill -3 46591 #向子進程發送3號信號,即QUIT信號,也未退出,說明QUIT信號也被忽略
ps -a
PID TTY TIME CMD
24345 pts/19 00:00:00 telnet
44710 pts/17 00:00:00 sudo
44746 pts/17 00:00:00 sudo
44747 pts/17 00:00:00 sort
44748 pts/17 00:00:00 sudo
44749 pts/17 00:00:00 sort
44750 pts/17 00:00:00 sudo
44751 pts/17 00:00:00 sort
44759 pts/17 00:00:00 su
44760 pts/17 00:00:00 bash
45497 pts/17 00:00:00 vi
45498 pts/17 00:00:00 vi
46590 pts/17 00:00:00 subsig.sh
46591 pts/17 00:00:00 forever.sh
46611 pts/17 00:00:00 sleep
46612 pts/17 00:00:00 ps
kill 46590 #向父進程發送TERM信號
ps -a
PID TTY TIME CMD
24345 pts/19 00:00:00 telnet
44710 pts/17 00:00:00 sudo
44746 pts/17 00:00:00 sudo
44747 pts/17 00:00:00 sort
44748 pts/17 00:00:00 sudo
44749 pts/17 00:00:00 sort
44750 pts/17 00:00:00 sudo
44751 pts/17 00:00:00 sort
44759 pts/17 00:00:00 su
44760 pts/17 00:00:00 bash
45497 pts/17 00:00:00 vi
45498 pts/17 00:00:00 vi
46590 pts/17 00:00:00 subsig.sh #父進程未被殺掉
46591 pts/17 00:00:00 forever.sh
46619 pts/17 00:00:00 sleep
46620 pts/17 00:00:00 ps
kill 46591 #向子進程發送TERM信號
Terminated #子進程立即終止
You want to kill me #打印出父進程的log
[1]+ Exit 143 ./subsig.sh #父進程終止
ps -a
PID TTY TIME CMD
24345 pts/19 00:00:00 telnet
44710 pts/17 00:00:00 sudo
44746 pts/17 00:00:00 sudo
44747 pts/17 00:00:00 sort
44748 pts/17 00:00:00 sudo
44749 pts/17 00:00:00 sort
44750 pts/17 00:00:00 sudo
44751 pts/17 00:00:00 sort
44759 pts/17 00:00:00 su
44760 pts/17 00:00:00 bash
45497 pts/17 00:00:00 vi
45498 pts/17 00:00:00 vi
46626 pts/17 00:00:00 ps
