我有一个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括号周围的索引。双引号和类似于$PIPESTATUSvs${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/

10-11 22:06
查看更多