如何在YQ表达式中使用动态变量?传Shell变量查询返回空问题
问题现象
- 现有配置文件
myres.txt存储如下JSON数组内容:
[ { "name": "test-001", "is_preconfigured": true, }, { "name": "my-connector", "is_preconfigured": 3 }, { "name": "checkerfrom_default2_002", "is_preconfigured": false, } ]
- 执行固定值匹配命令时可正常返回结果
my-connector,命令如下:
yq e '. | .[].name | select(. == "my-connector")' myres.txt
- 使用Shell动态变量传参时无预期返回,执行后结果为空,错误写法如下:
NAME_IN_YAML="my-connector" EXISTING_NAME=$(yq e '. | .[].name | select(. == $NAME_IN_YAML)' myres.txt)
故障原因
yq不会自动识别单引号包裹的表达式内的Shell变量,直接写$NAME_IN_YAML时,yq会把它当成自身上下文里的内部变量,这个变量没有被赋值是空值,select的匹配条件永远不成立,自然返回空结果。
正确传参方法
最稳妥、跨版本通用的写法是用--arg参数显式把Shell变量传给yq,不会有转义问题,也没有命令注入风险:
# 先定义Shell变量 NAME_IN_YAML="my-connector" # 传参查询:--arg 后面第一个参数是yq表达式内使用的变量名,第二个是要传入的Shell变量值 EXISTING_NAME=$(yq e --arg target_name "$NAME_IN_YAML" '.[].name | select(. == $target_name)' myres.txt)
执行完上面的命令,EXISTING_NAME变量就能正常拿到my-connector的结果,另外表达式开头的. |是多余的,可以直接删掉不影响执行。
如果你用的是依赖jq的Python版本yq,也可以用环境变量的方式传值:
# 先把变量导出为环境变量 export NAME_IN_YAML="my-connector" # 表达式里加env.前缀就能读取对应环境变量 EXISTING_NAME=$(yq e '.[].name | select(. == env.NAME_IN_YAML)' myres.txt)
踩坑提醒:别图省事把yq表达式外层的单引号换成双引号,靠Shell自动展开变量传值。这种写法只要变量值里带空格、引号、正则特殊字符就会直接执行报错,还存在命令注入的安全隐患。
内容的提问来源于stack exchange,提问作者Dnyaneshwar Jadhav
相关产品推荐
相关产品推荐

