我有一个shell脚本,它执行一个基本上是C程序的程序fuseIO
。
THE想法是,这个可执行的fuseIO
可以在它里面用一个SIGABRT
调用抛出一个abort( )
,在这种情况下,while循环应该退出。
如何做到这一点?
i=0
while [ $i != 10 ]
do
echo "************ Iteration: $i *********\n" 2>&1 |tee -a log.txt
./fuseIO 2>&1 | tee -a log.txt // This may throw SIGABRT
i=`expr $i + 1`
sleep 1
done
最佳答案
在某种程度上,请参见“磁盘碎片整理程序”告诉您进程已发出信号,但shell编码有一个问题,它通过将一个信号输出状态编码为128 +信号号(129为int,130为int等)来解决这个问题。演示shell和信号退出状态:
$ cat killme.sh
#!/bin/bash
kill ${1:-"-INT"} $$
$ ./killme.sh -HUP; echo $?
Hangup: 1
129
$ ./killme.sh -TERM; echo $?
Terminated: 15
143
$ ./killme.sh -QUIT; echo $?
0
$ ./killme.sh -PIPE; echo $?
141
$ ulimit -a
core file size (blocks, -c) 0
...
$
这或多或少证明了我的“128+signum”声明的合理性(这种行为是意外的,但可以用某种方式解释——它通常会转储内核,但不是因为
-QUIT
禁用了它们)。在
ulimit
中,您可以通过数组AA>获得最近执行的前景管道中的进程的退出状态值列表(它可能只包含一个命令)。例如:$ ./killme.sh | exit 31
$ echo ${PIPESTATUS[*]}
130 31
$
这相当于130的退出状态(2),加上显式退出状态31。注意符号:
bash
括号周围的索引。双引号和类似于$PIPESTATUS
vs${PIPESTATUS[0]}
vs$*
vs$@
vs"$*"
的操作可以获取数组中的所有值。应用于由两部分组成的管道,您应该能够测试:
if [[ ${PIPESTATUS[0]} == 134 ]]
then : FuseIO crash with SIGABRT
fi
没有
"$@"
,您可以简单地测试| tee
:if [[ $? > 128 && $? < 160 ]]
then : died a signalled death (probably)
else : died an ordinary death
fi
这里的160也是有根据的猜测;应该是128+SIGRTMAX。注意,如果进程确实
$?
,它将被视为已发出信号(即使没有)。关于c - 如何从正在执行可能会抛出文件的Shell脚本中捕获信号?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18364894/