常见Linux系统信号
信号 | 值 | 描述 |
---|
1 | SIGHUP | 挂起进程 | 2 | SIGINT | 终止进程 | 3 | SIGQUIT | 停止进程 | 9 | SIGKILL | 无条件终止进程 | 15 | SIGTERM | 尽可能终止进程 | 17 | SIGSTOP | 无条件停止进程,但不是终止进程 | 18 | SIGTSTP | 停止或暂停进程,但不终止进程 | 19 | SIGCONT | 继续运行停止的进程 |
默认情况下,bash shell会忽略收到的任何SIGQUIT(3)和SIGTERM(5)信号。但是bash shell会处理收到的SIGHUP(1)和SIGINT(2)信号。
如果bash shell收到了SIGHUP信号,比如当你要离开一个交互式shell,它就会退出。但在退出之前,它会将SIGHUP信号传给所有由该shell所启动的进程(包括正在运行的shell脚本)。
通过SIGINT信号,可以中断shell。Linux内核会停止为shell分配CPU处理时间。这种情况发生时,shell会将SIGINT信号传给所有由它所启动的进程,以此告知出现的状况。
生成信号
bash shell允许用键盘上的组合键生成两种基本的Linux信号。
- 中断进程
Ctrl+C 组合键会生成SIGINT信号,并将其发送给当前在shell中运行的所有进程。 - 暂停进程
Ctrl+Z 组合键会生成一个SIGTSTP信号,停止shell中运行的任何进程。停止(stopping)进程跟终止(terminating)进程不同:停止进程会让程序继续保留在内存中,并能从上次停止的位置 继续运行。在16.4节中,你会了解如何重启一个已经停止的进程。
捕获信号
trap命令允许你来指定shell脚本要监看并从shell中拦截的Linux信号。如果脚本收到了trap命令中列出的信号,该信号不再由shell处理,而是交由本地处理。
命令格式:trap commands signals
#!/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"
捕获脚本退出
除了在shell脚本中捕获信号,你也可以在shell脚本退出时进行捕获。 要捕获shell脚本的退出,只要在trap命令后加上EXIT信号就行。
#!/bin/bash
trap "echo Goodbye..." EXIT
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"
修改或移除捕获
#!/bin/bash
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 "echo ' I modified the trap!'" SIGINT
count=1
while [[ $count -le 5 ]]; do
echo "Second Loop #$count"
sleep 1
count=$[ $count + 1 ]
done
修改了信号捕获之后,脚本处理信号的方式就会发生变化。但如果一个信号是在捕获被修改前接收到的,那么脚本仍然会根据最初的trap命令进行处理。 也可以删除已设置好的捕获。只需要在trap命令与希望恢复默认行为的信号列表之间加上 两个破折号就行了。
#!/bin/bash
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命令中的设置进行处理。
|