前言
Linux利用信号与运行在系统中的进程进行通信。当你在终端中按下(Ctrl +C)Linux内核会停止为shell分配CPU处理时间。会生成SIGINT信号中断进程。而下面要将的是trap命令在信号出现时捕获他们并执行命令。
捕获信号
trap命令允许你来指定shell脚本要监看并从shell中拦截的Linux信号。如果在脚本收到了trap命令中列出的信号,该信号不再由shell处理,而是交给本地处理。
trap命令格式:
trap commands signals
现在通过一个例子,展示了如何用trap命令来忽略SIGINT信号,并控制脚本的行为:
#!/bin/bash
#测试信号捕获
trap "echo ' Sorry! I have trapped Ctrl-C'" SIGINT
echo "This is a test script"
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
echo "This is the end of the test script"
输出结果:
上面的例子中用到了trap命令会在每次检测到SIGINT信号时显示一行简单的文本信息。捕获这些信号会阻止用户用bash shell组合键Ctrl + C来停止程序。每次按下Ctrl + c组合键,脚本都会执行trap命令中指定的echo语句,而不是处理该信号并允许shell停止该脚本。
捕获脚本退出
除了在shell脚本中捕获信号,可以在shell脚本退出时进行捕获。要想捕获shell脚本的退出。只要在trap命令后加上EXIT信号就行。
#!/bin/bash
#捕获脚本退出信号
trap "echo \"Goodbye"\" EXIT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count +1 ]
done
输出结果:
当脚本运行时,正常退出位置时,会捕获就被触发了,shell会执行在trap命令行指定的命令。如果提前退出脚本,同样能够捕获到EXIT
移出捕获
要想在脚本中不同的位置进行不同的捕获处理,只需要重新使用带有新选项的trap命令。
trap -- SIGINT #终止脚本运行
可以在删除已设置好的捕获。只需要在trap命令与希望默认行为的信号列表之间加上两个破折号就行了。例如:
#!/bin/bash
#Modifying a set trap
trap "echo ' Sorry... Ctrl-C is trapped.'" SIGINT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
trap -- SIGINT
echo "I just removed the trap"
count=1
while [ $count -le 5 ]
do
echo "Second Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
输出结果:
在移除信号捕获后,脚本按照默认的行为来处理SIGINT信号,也就是终止脚本的运行。但如果信号是在捕获移除前接收到的,那么脚本会按照原先的trap命令中设置进行处理。
因为信号在捕获被移除前已经接收到了,脚本会按照旧的执行trap中指定的命令。捕获随后被移除,再按下Ctrl +c 就能够提前终止脚本。
总结
Linux 系统运行利用信号来控制shell脚本。当bash shell接受信号,并将它们传递给运行在改=该shell进程中的所有进程。可以在脚本中用trap语句来捕获信号并执行特定命令。
参考:Linux命令行与shell脚本编程大全