在壳管中捕获错误代码 [英] Catching error codes in a shell pipe

查看:86
本文介绍了在壳管中捕获错误代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个脚本,可以执行类似的操作

I currently have a script that does something like

./a | ./b | ./c

我想对其进行修改,以便如果a,b或c中的任何一个退出并显示错误代码,我都会打印一条错误消息并停止,而不是向前传递错误的输出.

I want to modify it so that if any of a, b or c exit with an error code I print an error message and stop instead of piping bad output forward.

最简单/最干净的方法是什么?

What would be the simplest/cleanest way to do so?

推荐答案

如果您真的不希望在知道第一个命令成功之前继续执行第二个命令,那么您可能需要使用临时文件.的简单版本是:

If you really don't want the second command to proceed until the first is known to be successful, then you probably need to use temporary files. The simple version of that is:

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",因此我使用了明确的表示法来保证年龄的可靠性.

The '1>&2' redirection can also be abbreviated '>&2'; however, an old version of the MKS shell mishandled the error redirection without the preceding '1' so I've used that unambiguous notation for reliability for ages.

如果您中断某些操作,这会泄漏文件.防弹(或多或少)的shell编程用途:

This leaks files if you interrupt something. Bomb-proof (more or less) shell programming uses:

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

当出现以下任何一个信号1 SIGHUP,2 SIGINT,3 SIGQUIT,13 SIGPIPE或15 SIGTERM或0(由于任何原因退出外壳时)时,第一条陷阱行都说'运行命令'rm -f $tmp.[12]; exit 1' . 如果您正在编写shell脚本,则最后一个陷阱只需删除陷阱0(即shell退出陷阱)即可(您可以将其他信号保留在原处,因为该过程无论如何都将终止).

The first trap line says 'run the commands 'rm -f $tmp.[12]; exit 1' when any of the signals 1 SIGHUP, 2 SIGINT, 3 SIGQUIT, 13 SIGPIPE, or 15 SIGTERM occur, or 0 (when the shell exits for any reason). If you're writing a shell script, the final trap only needs to remove the trap on 0, which is the shell exit trap (you can leave the other signals in place since the process is about to terminate anyway).

在原始管道中,'c'在'a'完成之前从'b'读取数据是可行的-这通常是合乎需要的(例如,它需要完成多个内核工作).如果'b'是'sort'阶段,则将不适用-'b'必须先查看其所有输入,然后才能生成其任何输出.

In the original pipeline, it is feasible for 'c' to be reading data from 'b' before 'a' has finished - this is usually desirable (it gives multiple cores work to do, for example). If 'b' is a 'sort' phase, then this won't apply - 'b' has to see all its input before it can generate any of its output.

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

If you want to detect which command(s) fail, you can use:

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

这是简单且对称的-扩展到4部分或N部分的管道很简单.

This is simple and symmetric - it is trivial to extend to a 4-part or N-part pipeline.

对'set -e'进行简单的实验没有帮助.

Simple experimentation with 'set -e' didn't help.

这篇关于在壳管中捕获错误代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆