为何Bash的set -e未按预期生效?
问题:为何启用
set -exuo pipefail后脚本仍未因文件不存在退出? 我在Bash脚本里启用了set -exuo pipefail,按预期脚本应该在首次出错时退出,但执行时即使操作了不存在的文件file_that_doesnt_exist.yaml,脚本依然输出了“no”,这是为什么?
脚本代码如下:
#!/bin/bash set -exuo pipefail # Run delorean to update the namespaces folder main() { if [ !$(yq -r '.random' file_that_doesnt_exist.yaml) = "true" ]; then echo "yes" else echo "no" fi } # shellcheck disable=SC2068 main $@
原因分析
set -e在条件判断中失效:set -e的规则是当命令以非零状态码直接执行并退出时终止脚本,但如果命令处于if、while等条件语句的表达式部分,Bash会捕获命令的退出码用于判断条件,不会触发set -e的终止逻辑。yq的错误被$(...)和[命令掩盖:yq读取不存在的文件会返回非零状态码,但它被包裹在$(...)中作为[命令的参数,此时if判断的是[命令的退出码,而非yq的错误状态。- 空字符串导致的比较逻辑错误:
yq执行失败时,$(...)返回空字符串,原条件[ !$(...) = "true" ]会被Bash解析为[ "!" = "true" ](空参数会被忽略),这个比较结果为假,因此进入else分支输出“no”。
内容的提问来源于stack exchange,提问作者Surya
相关产品推荐
相关产品推荐

