set -e
有一个例外情况,就是不适用于管道命令。
所谓管道命令,就是多个子命令通过管道运算符(|
)组合成为一个大的命令。Bash 会把最后一个子命令的返回值,作为整个命令的返回值。也就是说,只要最后一个子命令不失败,管道命令总是会执行成功,因此它后面命令依然会执行,set -e
就失效了。
请看下面这个例子。
#!/usr/bin/env bash set -e foo | echo a echo bar
执行结果如下。
$ bash script.sh a script.sh:行4: foo: 未找到命令 bar
上面代码中,foo
是一个不存在的命令,但是foo | echo a
这个管道命令会执行成功,导致后面的echo bar
会继续执行。
set -o pipefail
用来解决这种情况,只要一个子命令失败,整个管道命令就失败,脚本就会终止执行。
#!/usr/bin/env bash set -eo pipefail foo | echo a echo bar
运行后,结果如下。
$ bash script.sh a script.sh:行4: foo: 未找到命令
可以看到,echo bar没有执行。
set命令的-u/-e/-x/ -o pipefail这四个参数,一般都放在一起使用。
# 写法一 set -euxo pipefail # 写法二 set -eux set -o pipefail
这两种写法建议放在所有 Bash 脚本的头部。
另一种办法是在执行 Bash 脚本的时候,从命令行传入这些参数。
$ bash -euxo pipefail script.sh
参考资料
- The Set Builtin
- Safer bash scripts with 'set -euxo pipefail'
- Writing Robust Bash Shell Scripts
: » Shell bash 脚本 set -o pipefail 教程
原创文章,作者:wure,如若转载,请注明出处:https://blog.ytso.com/252574.html