You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:25:15