最近我在Ubuntu 14.04上学习POSIX shell的set -e
。我的参考资料是“IEEE Std 1003.1-2008,2016版”,“Shell& Utilities”一章。从this section我看到-e
在管道中命令失败时不会导致脚本退出(除非失败的命令是管道中的最后一个命令):
然后我写了一个简单的脚本来确认这种行为:多命令管道中任何单个命令的失败都不会导致shell退出。只考虑管道本身的故障。
(
set -e
false | true | false | true
echo ">> Multi-command pipeline: Last command succeeded."
)
(
set -e
false | true | false
echo ">> Multi-command pipeline: Last command failed."
)
打印出“Last command succeeded”消息,而“Last command failed”消息则不打印。
我的问题是:
false | true | false
似乎不是管道的失败。这只是最后一个命令的失败。 管道本身仍然成功。我是对的吗? false
来模拟命令的失败。是否有类似的管道命令?答案 0 :(得分:1)
默认情况下,bash中管道的成功或失败仅由管道中的最后一个命令决定。
但是,您可以启用pipefail
选项(set -o pipefail
),如果管道中的任何命令失败,管道将返回失败。
此管道成功:
$ false | true | false | true ; echo $?
0
此管道失败:
$ set -o pipefail
$ false | true | false | true ; echo $?
1
来自man bash
:
管道的返回状态是最后一个的退出状态 命令,除非启用了pipefail选项。如果是pipefail 启用后,管道的返回状态是最后一个的值 (最右边)命令以非零状态退出,如果全部退出则为零 命令退出成功。
答案 1 :(得分:1)
链式命令
false | true | false
似乎不是管道的失败。它只是最后一个命令的失败。管道本身仍然成功。我是对的吗?
管道的成功被指定为最后一个命令的成功。他们是一回事。
如果管道不以
!
保留字开头,退出状态应为管道中指定的最后一个命令的退出状态。否则,退出状态应为最后一个命令的退出状态的逻辑NOT。也就是说,如果最后一个命令返回零,则退出状态应为1;如果最后一个命令返回大于零,则退出状态应为零。
在bash和ksh中,如果其中的任何命令失败,您可以使用set -o pipefail
导致管道失败。不幸的是,这是not a POSIX option。它应该是,但它不是。