原创文章,转载请标明出处:無痕的碎碎念
本文链接地址:Shell Script - Trap
最近写 Shell 脚本的时候发现一个需求:
- 有一条(或组)命令不希望被打断执行,或者不能被打断执行。
举个例子来说,有一个时间比较长的追加写入操作,中间在执行过程中如果中断的话会很麻烦,要清理文件或者判断写到什么位置了。这时候如果有个方法能保证这个操作完成,不会因为手抖按了 C-c
被中断掉。
在不存在的网站 Google 上找了一下,在 Shell 中有一个捕获系统信号的命令 trap
。
用法
trap command signals
trap
在捕获到 signals
中定义的信号之后,会执行 command
指定的命令。
注意事项
虽然提供了这么一个命令来捕获系统信号,但是在实际使用的时候会发现很多信号捕获不了:
SIGSTOP
SIGKILL
此外,处于 Shell 的交互模式的时候,以下信号也捕获不了:
SIGTTIN
SIGTTOU
SIGTSTP
解决问题
上面说了这么多,然而并没有解决问题,虽然捕获了信号,但是还是会打断当前进行的操作。trap
在捕获到信号,执行指定的 command
的时候,会忽略掉其他的信号(当然 SIGKILL
和 SIGSTOP
这种没办法)。利用这一点,把需要保证完成的操作作为指定的 command
,然后在设置捕获信号之后马上对自己发出一个可以捕获的信号就可以了。1234assert() { trap '$@; trap - SIGINT' SIGINT kill -INT $$}
只要把需要执行的命令作为 assert
函数的参数传入就好了。
还有个问题
这个方法对 C-z
是无效的,不过可以利用它来结束掉这条指令。毕竟执行到一半发现什么奇怪的问题,需要结束这种情况还是难免的。