在shell管道中捕获错误代码

前端之家收集整理的这篇文章主要介绍了在shell管道中捕获错误代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前有一个脚本,做一些像
./a | ./b | ./c

我想修改它,以便如果任何a,b或c退出错误代码我打印一个错误信息,并停止,而不是管道坏的输出前进。

什么是最简单/最干净的方式这样做?

如果你真的不想让第二个命令继续,直到第一个命令已知是成功的,那么你可能需要使用临时文件。简单的版本是:
tmp=${TMPDIR:-/tmp}/mine.$$
if ./a > $tmp.1
then
    if ./b <$tmp.1 >$tmp.2
    then
        if ./c <$tmp.2
        then : OK
        else echo "./c Failed" 1>&2
        fi
    else echo "./b Failed" 1>&2
    fi
else echo "./a Failed" 1>&2
fi
rm -f $tmp.[12]

‘1& 2’重定向也可以缩写为“& 2”;然而,旧版本的MKS shell处理错误重定向没有前面的’1’,所以我使用了明确的符号的可靠性的年龄。

如果你中断某些东西,这会泄漏文件。防爆(或多或少)shell编程使用:

tmp=${TMPDIR:-/tmp}/mine.$$
trap 'rm -f $tmp.[12]; exit 1' 0 1 2 3 13 15
...if statement as before...
rm -f $tmp.[12]
trap 0 1 2 3 13 15

第一个陷阱行说’运行命令’rm -f $ tmp。当信号1 SIGHUP,2 SIGINT,3 SIGQUIT,13 SIGPIPE或15 SIGTERM中的任何一个出现时,或者当外壳出于任何原因退出时为0。
如果你正在编写一个shell脚本,最终陷阱只需要删除0陷阱,这是shell退出陷阱(你可以留下其他信号,因为进程即将终止)。

在原始流水线中,’c’在’a’完成之前从’b’读取数据是可行的 – 这通常是所期望的(例如,它给予多个核心工作)。如果’b’是一个’排序’阶段,那么这将不适用 – ‘b’必须看到所有的输入,然后才能生成任何输出

如果要检测哪些命令失败,可以使用:

(./a || echo "./a exited with $?" 1>&2) |
(./b || echo "./b exited with $?" 1>&2) |
(./c || echo "./c exited with $?" 1>&2)

这是简单和对称的 – 扩展到4部分或N部分管道是微不足道的。

简单的实验’set -e’没有帮助。

原文链接:https://www.f2er.com/bash/391878.html

猜你在找的Bash相关文章