如何让Linux管道执行失败?POSIX shell set -e特性疑问
关于POSIX Shell中
set -e在管道中的行为解析 最近我在Ubuntu 14.04系统上学习POSIX Shell的set -e特性时,特意翻了《IEEE Std 1003.1-2008, 2016 Edition》里的「Shell & Utilities」章节,发现了一个很容易被忽略的细节——当管道里的非最后一个命令失败时,set -e并不会触发脚本退出。
POSIX标准里对此有明确的定义:
多命令管道中单个命令的失败不应使shell退出,仅需考虑管道本身的执行结果。
简单来说,set -e的退出逻辑只看管道整体的返回值,而管道的返回值默认是最后一个命令的退出码。哪怕前面的命令跑失败了,只要最后一个命令正常返回0,脚本就会继续执行下去。
我特意写了个小脚本验证这个行为:
#!/bin/sh set -e # 第一个命令故意返回失败,第二个命令正常输出 false | echo "管道里的第二个命令正常执行" echo "脚本还在继续运行哦!"
运行这个脚本后,你会看到两行输出都打印出来了——false的失败并没有触发set -e的退出机制,因为管道的整体返回码是最后一个echo命令的0,符合set -e的“仅在命令非零退出时退出”的逻辑。
如果你的脚本是基于Bash的,想要让管道中任意一个命令失败就触发脚本退出,可以额外加上set -o pipefail选项,但要注意这个是Bash的扩展特性,不属于POSIX标准,在纯POSIX Shell环境下是不支持的。
内容的提问来源于stack exchange,提问作者yaobin
相关产品推荐
相关产品推荐

