检查后台进程的可能退出代码

时间:2014-01-07 15:36:29

标签: bash

考虑以下代码:

myprocess | while read line; do logger -t mytag -p user.err $line; done &

if [ ${PIPESTATUS[0]} -ne 0 ]; then
   logger -t ${tag} -p user.error "CANNOT START (exit code: ${PIPESTATUS[0])"
fi

如果myprocess没有失败,那么PIPESTATUS [0]是什么,未定义? 如何检查myprocess在启动时是否已启动或死亡(缺少库符号等),同时仍然捕获其输出?

谢谢, 丹

3 个答案:

答案 0 :(得分:1)

这个怎么样:

{ myprocess 2>&1 || echo "CANNOT START (exit code: $?)" ; } \
| while read line; do logger -t mytag -p user.err $line; done

2>&1将允许您捕获并记录错误输出以及标准输出。

答案 1 :(得分:0)

如果myprocess没有失败,${PIPESTATUS[0]}将为0

或者,set -o pipefail。如果$?失败并且您不需要检查myprocess,那么完整命令(PIPESTATUS)的退出状态将为非零。

答案 2 :(得分:0)

这可能会变得棘手。您需要从背景作业返回$ {PIPESTATUS [n]} 。我通过创建一个函数并传入命令作为参数运行然后将整个事件发送到后台来做一些非常类似的事情。注意pipe_command()函数中的return语句。这将返回$ cmd的状态,而不是while读取行循环。您也可以使用此技术在for循环中处理多个事物。希望这会有所帮助。

示例:

#! /bin/bash

main()
{
    pids=""
    myprocess="ssh user@node /bin/bash /etc/init.d/process start"
    pipe_command "$myprocess" &
    pids+="$! "
    watch_pids "$pids"
}

pipe_command()
{
    cmd="$1"
    $cmd 2>&1 | \
    while read line; do
        logger -t mytag -p user.err $line
    done
    return ${PIPESTATUS[0]}
}

watch_pids()
{
    pids="$1"
    for pid in $pids; do
        wait $pid
        if [ $? -ne 0 ]; then
            logger -t ${tag} -p user.error "CANNOT START (exit code: $?)"
            return 2
        fi
    done
}
main $@

或者更简单地举例来说:

myprocess | while read line; do logger -t mytag -p user.err $line; done ; return ${PIPESTATUS[0]} &

wait
status=$?
if [ $status -ne 0 ]; then
   logger -t ${tag} -p user.error "CANNOT START (exit code: $status)"
fi