使用yq将Map合并到values.yaml时遇报错,求排查方案
问题:使用yq向values.yaml添加多Map结构时出现"Cannot multiply !!null with !!map"错误
原脚本
FILES=$(ls -1 | grep "values-.*.yaml") for i in $FILES; do yq e '.applications *= { "'$i'":{ "enabled":"true", "destination":{ "namespace":"x", "server":"wwww" }, "source":{ "chart":"'$i'" } } }' values.yaml done
错误信息
Error: Cannot multiply !!null with !!map
期望生成的YAML格式
applications: a: enabled: "true" destination: namespace: x server: wwww source: chart: a b: enabled: "true" destination: namespace: x server: wwww source: chart: b
错误原因
- 初始值为null导致合并失败:如果
values.yaml中一开始没有applications键,它的默认值是null,而*=操作符仅支持两个已存在的Map类型合并,无法将null与Map执行相乘操作,因此触发错误。 - 循环未修改原文件且存在覆盖问题:当前脚本每次循环都读取原始
values.yaml处理,结果仅输出到终端而非写入文件;同时每次处理都基于原始文件,最终只会保留最后一个文件的配置,无法累积所有条目。
修正方案
方案1:先初始化applications为空Map,再循环合并写入文件
# 先确保applications是一个空Map(不存在或为null时自动初始化) yq e '.applications //= {}' -i values.yaml FILES=$(ls -1 | grep "values-.*.yaml") for i in $FILES; do # 每次循环将新条目合并到applications,并直接修改原文件 yq e '.applications += { "'$i'":{ "enabled":"true", "destination":{ "namespace":"x", "server":"wwww" }, "source":{ "chart":"'$i'" } } }' -i values.yaml done
优化说明
- 使用
//=操作符:自动初始化applications为空Map,确保后续合并操作有合法的Map类型对象。 - 使用
+=替代*=:语义更直观,表示向Map中添加新键值对,效果与*=一致。 - 添加
-i参数:让yq直接修改原文件,循环的修改会累积到文件中,而非仅输出到终端。
方案2:使用yq环境变量避免shell引号问题(推荐)
如果使用的是mikefarah/yq v4+版本,可通过环境变量传递文件名,避免shell字符串替换的引号问题:
yq e '.applications //= {}' -i values.yaml FILES=$(ls -1 | grep "values-.*.yaml") for i in $FILES; do i="$i" yq e '.applications += { env(i):{ "enabled":"true", "destination":{ "namespace":"x", "server":"wwww" }, "source":{ "chart": env(i) } } }' -i values.yaml done
内容的提问来源于stack exchange,提问作者Andres Cabrera
相关产品推荐
相关产品推荐

