yq 如何用 -e 退出状态码在脚本中判断查询结果为空或 false
2026/9/15 10:03:45 网站建设 项目流程

yq 如何用 -e 退出状态码在脚本中判断查询结果为空或 false

【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq

写自动化脚本时经常要判断"配置文件里某个字段是否存在、值是否为 false",但 yq 查询不到内容时照样会打印null,光看输出文本无法可靠分支。yq 为此提供了-e--exit-status)标志:当查询结果"没有匹配、是 null、或返回 false"时,进程以非零退出码结束,脚本就能用标准的if/$?机制直接判断。

适用前提:机器上已安装 yq,目标文件是 yq 支持解析的格式(未知扩展名默认按 YAML 处理,见 README 中的 Usage 说明)。

先确认环境

yq -V

-V--version)打印版本信息后退出,README 的 Flags 列表中有此标志。如果命令不存在,先安装 yq,README 列出了多种方式,例如 MacOS/Linux 上用 Homebrew:

brew install yq

Linux 上也可以用 snap:

snap install yq

README 还列出了从项目 Releases 下载预编译二进制、以及用 Docker/Podman 一次性运行(docker run --rm -v "${PWD}":/workdir mikefarah/yq <表达式> <文件>)等途径。本文场景是脚本中长期调用,建议本地安装。

-e 的具体判定规则

README 中对该标志的描述是:

-e, --exit-status set exit status if there are no matches or null or false is returned

即只有三种情况返回非零退出状态:没有匹配、结果为null、结果为false。源码对这条规则的实现细节可以核对到三处:

  • 触发位置:eval(默认命令)执行完表达式后检查"是否真的打印过内容",没有则报错no matches found,见 cmd/evaluate_sequence_command.go;eval-all命令有同样的检查,见 cmd/evaluate_all_command.go。
  • "打印过内容"的判定:结果节点不是!!null且不是!!boolfalse才算打印过,见 pkg/yqlib/printer.go。也就是说nullfalse不算,其他值——包括0、空字符串——都算。
  • 退出码:任何错误都让进程以 1 退出,见 yq.go。

一个容易被忽略的副作用:-e不抑制 stdout。查询不存在的字段时,null仍会正常打印到 stdout,同时 stderr 输出no matches found,退出码为 1。脚本里需要把"取输出"和"看退出码"分开处理。

最小示例:对文件字段做判断

用仓库自带的 examples/small.yaml,内容如下:

--- # comment # about things a: cat

两个查询的退出码不同(下面的输出与退出码为按上述规则得到的示例结果,可在本地复现):

yq -e '.a' examples/small.yaml echo $? # 0:.a 存在,值是 "cat",属正常结果
yq -e '.missing' examples/small.yaml echo $? # 1:字段不存在,结果为 null

第二条命令的 stdout 打印null,但退出码是 1,stderr 含no matches found错误。

在脚本中使用

标准的分支写法:

if yq -e '.a' examples/small.yaml; then echo "字段 .a 存在,且值不是 null/false" else echo "字段 .a 不存在,或值为 null/false" fi

如果还要取到值本身,可以先捕获输出再看退出码:

value=$(yq -e '.a' examples/small.yaml) if [ $? -eq 0 ]; then echo "value: $value" else echo "no valid value" fi

命令替换的退出码就是 yq 的退出码,$?紧跟在其后即可读取。

用 null 输入验证四类结果

README 中的-n--null-input)表示不读输入文件、直接求值表达式,可以不用建文件就核对每个边界(示例结果):

yq -e -n 'false'; echo $? # 输出 false,退出码 1 yq -e -n 'null'; echo $? # 输出 null, 退出码 1 yq -e -n 'true'; echo $? # 输出 true, 退出码 0 yq -e -n '0'; echo $? # 输出 0, 退出码 0

这四条正好覆盖-e的规则边界:只有nullfalse被判为非零,0是正常结果,不会被误判为失败。

多文档场景(可选)

处理多文档 YAML 时用eval-all(README 中的子命令,一次加载所有文档再执行表达式)。-e的检查在该路径同样生效(见上文 cmd/evaluate_all_command.go 的引用):表达式在所有文档中都没有匹配时,退出码同样非零。

限制

  • 不加-e时,上面所有查询(包括无匹配)退出码都是 0;非零检查只在开启该标志后执行(cmd/evaluate_sequence_command.go 的条件里包含exitStatus)。
  • 失败退出码固定为 1,项目没有区分"无匹配"与其他错误的退出码(yq.go 统一os.Exit(1))。如果脚本需要区分"查不到值"和"文件解析失败",只能进一步检查 stderr 里的错误消息。
  • -e是定义在根命令上的持久标志(cmd/root.go),默认evaleval-all均可用;项目文档没有给出失败原因到退出码的映射表,脚本中按"非零即失败"处理即可。

需要更多标志(如-n-e-o等)的完整列表时,见 README 的 Usage 一节。

【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询