Linux Shell接受处理信号trap指令
它有三种形式分别对应三种不同的信号回应方式.
第一种:
trap 'commands' signal-list
当脚本收到signal-list清单内列出的信号时,trap命令执行双引号中的命令.
第二种:
trap signal-list
trap不指定任何命令,接受信号的默认操作.默认操作是结束进程的运行.
第三种:
trap ' ' signal-list
trap命令指定一个空命令串,允许忽视信号.
NOTE:trap 对同种signal只能相应一种设定,如果在一个shell里面设置多个trap,如:
trap ' echo “aaaaaaaaaaa” ' INT
trap ' echo “bbbbbbbbbbb” ' INT
那么它只会响应最后一个信号设定。
信号处理(Signal Handling)在 Linux 编程中一直扮演者重要的角色,几乎每个系统工具都要用到它,最常见的功能莫过于用信号进行进程间通信(尤其是父子进程)以及捕捉SIGINT、SIGTERM之类的退出信号以做一些善后处理(cleanup)。C中自不必多说,可以使用 wait 族函数;而 shell 脚本中也有捕捉信号的 trap 功能——然而许多人在使用 trap 功能的时候却存在着这样那样的误解,这些看似无关紧要的小细节最后有可能使得你的脚本与你预想的行为完全不同。
condition 中的信号到底应该如何书写?比如终端中断信号(一般用 CTRL-C 发出),到底是写 SIGINT 、 INT 还是2(大部分系统上该信号对应的信号数)?是大写还是小写?
如果你使用最新版的 Bash ,那么这几种写法都可以。而如果你需要在不同 shell 中保持可移植性,请使用大写、不带前缀的 INT !根据 POSIX 标准, trap 的 condition 不应当加上 SIG 前缀,且必须全大写,允许带 SIG 前缀或小写是某些 shell 的扩展功能。而信号数在不同的系统上可能不同,所以也不是一个好主意。
trap 可以根据你的需要放在脚本中的任何位置。脚本中也可以有多个 trap ,可以为不同的信号定义不同的行为,或是修改、删除已定义的 trap 。更进一步地, trap 也有作用范围,你可以把它放在函数中,它将只在这个函数里起效!
如果当前正有一个外部命令在前台执行,那么 trap 会等待当前命令结束以后再处理信号队列中的信号。
for file in $(ls)
do
trap 'echo "testing..." ; exit' INT
echo "sleeping"
sleep 2
done
信号分类
------------------------------------------
名称 默认动作 说明
SIGHUP 终止进程 终端线路挂断
SIGINT 终止进程 中断进程
SIGQUIT 建立CORE文件 终止进程,并且生成core文件
SIGILL 建立CORE文件 非法指令
SIGTRAP 建立CORE文件 跟踪自陷
SIGBUS 建立CORE文件 总线错误
SIGSEGV 建立CORE文件 段非法错误
SIGFPE 建立CORE文件 浮点异常
SIGIOT 建立CORE文件 执行I/O自陷
SIGKILL 终止进程 杀死进程
SIGPIPE 终止进程 向一个没有读进程的管道写数据
SIGALARM 终止进程 计时器到时
SIGTERM 终止进程 软件终止信号
SIGSTOP 停止进程 非终端来的停止信号
SIGTSTP 停止进程 终端来的停止信号
SIGCONT 忽略信号 继续执行一个停止的进程
SIGURG 忽略信号 I/O紧急信号
SIGIO 忽略信号 描述符上可以进行I/O
SIGCHLD 忽略信号 当子进程停止或退出时通知父进程
SIGTTOU 停止进程 后台进程写终端
SIGTTIN 停止进程 后台进程读终端
SIGXGPU 终止进程 CPU时限超时
SIGXFSZ 终止进程 文件长度过长
SIGWINCH 忽略信号 窗口大小发生变化
SIGPROF 终止进程 统计分布图用计时器到时
SIGUSR1 终止进程 用户定义信号1
SIGUSR2 终止进程 用户定义信号2
SIGVTALRM 终止进程 虚拟计时器到时