如何在此陷阱捕获的bash脚本中使外部程序可中断?

时间:2015-04-26 18:13:52

标签: bash signals

我正在编写一个脚本,它将运行一个外部程序(dbconsole),如果它被POSIX信号或命名管道上的输入中断,则进行一些清理。这是完整的草案

arecord

这样可以完美地工作:脚本在信号到达时结束,如果写入fifo则生成信号。

但是我没有#!/bin/bash X=`date '+%Y-%m-%d_%H.%M.%S'` F=/tmp/$X.wav P=/tmp/$X.$$.fifo mkfifo $P trap "echo interrupted && (rm $P || echo 'couldnt delete $P') && echo 'removed fifo' && exit" INT # this forked process will wait for input on the fifo (echo 'waiting for fifo' && cat $P >/dev/null && echo 'fifo hit' && kill -s SIGINT $$)& while true do echo waiting... sleep 1 done #arecord $F 循环而是想要现在注释掉的while true命令,但是如果我运行该程序而不是循环,则SIGINT不会陷入陷阱和{ {1}}继续运行。

我该怎么办?

1 个答案:

答案 0 :(得分:1)

听起来你真的需要这个工作更像init脚本。所以,在后台启动arecord并将pid放在一个文件中。然后使用陷阱根据pidfile终止arecord进程。

#!/bin/bash
PIDFILE=/var/run/arecord-runner.pid #Just somewhere to store the pid
LOGFILE=/var/log/arecord-runner.log

#Just one option for how to format your trap call
#Note that this does not use &&, so one failed function will not
# prevent other items in the trap from running
trapFunc() {
    echo interrupted
    (rm $P || echo 'couldnt delete $P')
    echo 'removed fifo'
    kill $(cat $PIDFILE)
    exit 0
}

X=`date '+%Y-%m-%d_%H.%M.%S'`

F=/tmp/$X.wav
P=/tmp/$X.$$.fifo

mkfifo $P

trap "trapFunc" INT

# this forked process will wait for input on the fifo
(echo 'waiting for fifo' && cat $P >/dev/null && echo 'fifo hit' && kill -s SIGINT $$)&

arecord $F 1>$LOGFILE 2>&1 &  #Run in the background, sending logs to file
echo $! > $PIDFILE  #Save pid of the last background process to file
while true
do
    echo waiting...
    sleep 1
done

另外......你可能会用'&&'来写你的陷阱条款有一个原因,但作为替代方案,你可以像我上面那样给出一个函数名,或者像这样的一种匿名函数:

trap "{ command1; command2 args; command3; exit 0; }"

只需确保每个命令后跟分号,并且大括号和命令之间有空格。使用&& amp;的风险在陷阱中,如果退出之前的一个命令无法执行,你的脚本将继续运行中断(但也许你想要那个?)。