我正在编写一个脚本,它将运行一个外部程序(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}}继续运行。
我该怎么办?
答案 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;的风险在陷阱中,如果退出之前的一个命令无法执行,你的脚本将继续运行中断(但也许你想要那个?)。