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 yqLinux 上也可以用 snap:
snap install yqREADME 还列出了从项目 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且不是!!bool的false才算打印过,见 pkg/yqlib/printer.go。也就是说null和false不算,其他值——包括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的规则边界:只有null与false被判为非零,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),默认eval与eval-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),仅供参考