Linux——处理信号

常见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命令中的设置进行处理。

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/121207046
今日推荐