Bash脚本中set -o pipefail的含义是什么?

65

在shell脚本开头加上set -o pipefail是什么意思?

1个回答

74

man bash说:

pipefail如果设置,则管道的返回值是退出状态为非零的最后一个(最右边的)命令的值,如果管道中所有命令都成功退出,则返回零。此选项默认处于禁用状态。

这里的“管道”指的是:

command1 | command2 | command3

如果没有使用 pipefail,管道的返回值就是管道中最后一个命令的退出状态码,无论之前的命令是否失败。

举例:

$ grep ^root /etc/passwd | cut -f 5 -d :
System Administrator
$ echo $?
0
$ grep ^nonexistant_user /etc/passwd | cut -f 5 -d :
$ echo $?
0
$ set -o pipefail
$ grep ^nonexistant_user /etc/passwd | cut -f 5 -d :
$ echo $?
1

4
在使用管道时,是否建议/必要使用 pipefail - User123
3
@User123 这取决于您是否希望管道在其中一个组件失败时返回非零值。 - oguz ismail
8
@User123: 这取决于你使用管道的原因以及管道的功能。如果你使用cat从/dev/urandom获取随机字节数据并将其发送到xxd和head,则可能不需要设置pipefail:因为cat命令永远无法成功完成。但是,如果你使用帮助函数从常规命令生成更有用的日志,但需要常规命令的退出状态,则需要设置pipefail。 - Jack Simth
7
是的,这取决于情况。一个广泛的例子是管道中的 grep - 如果没有找到,则返回1。但我想知道是否(统计上)默认更常见的是通过默认方式检测失败,而不是通过最后一个命令中的0来“吞没”它(特别是在脚本中)。个人而言,我在所有脚本中都启用了它,并通过显式检查退出代码来解决问题。我认为启用 pipefail 是更明智的默认值。 - uvsmtid
2
提示:set -euo pipefail会在子进程失败、尝试使用未设置的变量或管道失败时退出。 - NeilG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接