Show using a short BASH script how to prevent a process from responding to a <CTRL-C>(SIGINT) for 20 seconds and then reenable <CTRL-C> and remain in a loop until the user hits <CTRL+C>
# 关于 trap
当进程接收到信号时,将调用相应的 trap
。 trap
命令允许用户指定一个命令,或一个函数,即当 shell
接收到特定信号时执行。 Ctrl-Z
和 Ctrl-C
键输入直接使用信号。 trap
命令导致在一个或多个信号到达时 shell
执行指定的命令。如果有大量的信号到达,它们就会按编号顺序进行处理。
# 关于信号
POSIX
已经标准化了 UNIX
的信号处理方案。每个信号都有一个以前缀 SIG
开头的符号名称。每个信号都与一个整数标识符号及其符号名称相关联。
Signal | 编号 | 解释 |
---|---|---|
SIGHUP | 1 | 挂起 - 控制终端不再连接 |
SIGINT | 2 | 中断 - 通常来自键盘 (Ctrl-C) |
SIGQUIT | 3 | 退出 - 用户已经按下了一个退出键 (Ctrl-\) |
SIGKILL | 9 | 杀死 - 无法被捕获或被忽略,立即结束指定进程 |
SIGTERM | 15 | 进程终止信号, kill 命令默认选项 |
SIGHUP
, UNIX
挂起信号,用于表示终端不再连接。默认情况下,该信号将终止该进程,通过使用 trap
命令,可以编程指定对 SIGHUP
信号的响应,或对其他信号的响应。
kill
命令用于使用 kill –(SignalNumber)/(SignalName) ProcessID
向正在运行的进程发送信号 (preferred to use signal names, rather than signal numbers)
# 使用 trap
trap 'command' <signal list>
注意 trap
命令中使用单引号。 signal list
通常是一个单一的信号,但也可以是一个信号列表, trap 'echo “This is a trap”' SIGINT SIGHUP
,可以使用信号量编号也可以直呼其名。 command
可以是单个命令 trap 'echo “This is a trap”' 1
,也可以是多个命令, trap 'echo “This is a trap” ; exit 1' 1
当接收到任何一个信号时,则执行指定的命令。下面是一个使用 trap
命令的简单示例程序。程序将持续循环,但如果向该程序发送信号信号,将显示 “This is a trap”
信息退出。
#! /bin/bash | |
trap 'echo “This is a trap” ; exit' INT | |
while true; do | |
echo “I’m looping” | |
sleep 1 | |
done |
如果该命令为空字符串,则将忽略信号,比如: trap ' ' SIGINT
,这是一种忽略信号中断的方法;但是, 信号9(SIGKILL)
不能被忽略。
# Step 1
用 shell
编程,暂时能想到的办法只有 trap
和 SIGINT
的使用,循环控制变量 i
初值 20
,循环间隔 1s 打印 asleep
屏蔽 SIGINT
并递减,判断 i 是否小于 0
了,是则打印 wake
,不过停不下来
#!/usr/bin/env bash | |
i=20 | |
trap ' ' SIGINT | |
while [ 1 ] | |
do | |
sleep 1 | |
if (($i>0)); then | |
echo asleep | |
else | |
echo wakeup | |
fi | |
i=$(($i-1)) | |
done |
# Step 2
条件判断否加入退出 INT
即可
trap 'echo "_INTERRUPTED!"; exit' INT |
# End
#!/usr/bin/env bash | |
i=5 | |
trap " " SIGINT | |
while [ 1 ] | |
do | |
sleep 1 | |
if (($i>0)); then | |
echo asleep | |
else | |
echo wake | |
trap 'echo "_INTERRUPTED!"; exit' INT | |
fi | |
i=$(($i-1)) | |
done |
最后别忘了改数值,本题问的可是 20s