代码之家  ›  专栏  ›  技术社区  ›  yaobin Anycorn

如何导致Linux管道失败?

  •  4
  • yaobin Anycorn  · 技术社区  · 7 年前

    最近我在学习 set -e Ubuntu 14.04上的POSIX外壳。我的参考资料是“IEEE Std 1003.1-2008,2016版”,“壳牌与公用事业公司”章节。从…起 this section 我明白了 -e 当命令在管道中失败时,不会导致脚本退出(除非失败的命令是管道中的最后一个命令):

    多命令管道中的任何单个命令失败不得导致外壳退出。仅考虑管道本身的故障。

    然后,我编写了一个简单的脚本来确认这种行为:

    (
        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 Successed”(最后一个命令成功)消息,而不会打印“Last command failed”(最后一个命令失败)消息。

    我的问题是:

    • 链接命令 false | true | false 这似乎不是管道故障。这只是最后一个命令的失败。 管道本身仍然成功。我说得对吗??
    • 有没有办法模拟管道故障?? 我们可以使用 false 模拟命令失败。管道是否有类似的命令?
    2 回复  |  直到 7 年前
        1
  •  4
  •   John1024 David C. Rankin    7 年前

    在bash中,默认情况下,管道的成功或失败完全由管道中的最后一个命令决定。

    但是,您可以启用 pipefail 选项( set -o pipefail )如果管道中的任何命令失败,管道将返回failure。

    实例

    此管道成功:

    $ false | true | false | true ; echo $?
    0
    

    此管道出现故障:

    $ set -o pipefail
    $ false | true | false | true ; echo $?
    1
    

    文档

    从…起 man bash :

    管道的返回状态是最后一个管道的退出状态 命令,除非启用了pipefail选项。如果pipefail为 启用后,管道的返回状态为最后一个 (最右侧)以非零状态退出的命令,如果全部为零,则为零 命令成功退出。

        2
  •  1
  •   John Kugelman Michael Hodel    7 年前

    链接命令 false | true | false 这似乎不是管道故障。这只是最后一个命令的失败。管道本身仍然成功。我说得对吗?

    管道的成功指定为最后一个命令的成功。他们是同一件事。

    从…起 §2.9.2 Pipelines :

    如果管道不是从 ! 保留字, 退出状态应为管道中指定的最后一个命令的退出状态 。否则,退出状态应为最后一个命令退出状态的逻辑NOT。即,如果最后一个命令返回零,则退出状态应为1;如果最后一个命令返回的值大于零,则退出状态应为零。

    在bash和ksh中,可以使用 set -o pipefail 如果管道中的任何命令失败,则导致管道失败。这是 not a POSIX option 不幸地应该是,但不是。