告知左侧故障管道的右侧?

Bit*_*nce 23 bash pipeline pipe

我喜欢在shell脚本中的函数之间使用类似生成器的模式.像这样的东西:

parse_commands /da/cmd/file | process_commands
Run Code Online (Sandbox Code Playgroud)

但是,这种模式的基本问题是,如果parse_command遇到错误,我发现通知process_command失败的唯一方法是通过显式告知它(例如echo"FILE_NOT_FOUND").这意味着必须对parse_command中的每个可能的错误操作进行隔离.

难道没有办法使用非零退出代码检测左侧是否退出?

let*_*man 29

set -o pipefail在bash脚本的顶部使用,以便当管道左侧出现故障(退出状态!= 0)时,右侧不会执行.

  • "set -o pipefail"不会阻止右侧执行,因此它不回答"如何通知右侧......"的初始问题.基本上这会改变管道的退出状态:默认情况下,管道的退出状态是右侧的退出状态,使用此选项,它是管道命令的最大值. (9认同)
  • 但这正是我所寻找的:-)所以它对我有所帮助.谢谢 (3认同)

Dav*_* W. 14

即使第一个流程已经结束,管道流程是否仍在继续,或者是您无法知道第一个流程失败的问题?

如果是后者,您可以查看PIPESTATUS变量(实际上是BASH数组).这将为您提供第一个命令的退出代码:

parse_commands /da/cmd/file | process_commands
temp=("${PIPESTATUS[@]}")
if [ ${temp[0]} -ne 0 ]
then
    echo 'parse_commands failed'
elif [ ${temp[1]} -ne 0 ]
then
    echo 'parse_commands worked, but process_commands failed'
fi
Run Code Online (Sandbox Code Playgroud)

否则,您将不得不使用协同进程.

  • 确实,这提供了信息,但它不能在 process_command 内部完成,因此可读性受到影响。 (2认同)

jjm*_*tes 5

与运算符(&&)不同,管道运算符(|)通过同时生成两个进程来工作,因此第一个进程可以将其输出传递给第二个进程,而无需缓冲中间数据.这允许在几乎没有内存或磁盘使用的情况下处理大量数据.

因此,第一个进程的退出状态在第二个进程完成之前不可用.