我有一个shell脚本,它正在执行一个基本上是C程序的程序fuseIO
。
这个想法是,这个可执行文件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
答案 0 :(得分:2)
在某种程度上,请参阅Exit status codes greater than — possible? WIFSIGNALED的内容告诉您已发出进程信号,但是shell编码存在问题,并且通过将发出信号的退出状态编码为128 +信号来实现数字(HUP为129,INT为130等)。要演示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
...
$
这或多或少证明了我的 + + signum'声明(-QUIT
行为是意料之外的,但可以在时尚之后解释 - 它通常会转储核心,但没有因为ulimit
已禁用它们。)
在bash
中,您可以从最近执行的前台管道(可能只包含一个命令)中的进程获取退出状态值列表。通过数组$PIPESTATUS
。例如:
$ ./killme.sh | exit 31
$ echo ${PIPESTATUS[*]}
130 31
$
这对应于SIGINT(2)的130退出状态加上显式退出状态31.注意符号:${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。请注意,如果某个流程执行exit 135
,则会将其视为已发出信号(即使它未发出信号)。