如何在Shell脚本中以开发者友好方式编写JSON参数
问题解答
1. 无需额外变量实现缩进JSON参数?
不行。Shell语法规则下,--patch=后直接跟换行缩进的JSON会被解析为多个独立命令参数,无法被识别为完整的JSON字符串,必须通过引号包裹或变量传递,所以你期望的无变量缩进写法无法直接运行。
2. 开发者友好的Shell脚本写法
方法一:用jq优化Heredoc(解决引号转义和缩进问题)
可以借助jq的变量注入功能,避免手动转义引号,同时让JSON保持清晰缩进:
kubectl patch deployment "${APP_NAME}" \ --patch="$(jq -n '{ spec: { template: { metadata: { annotations: { friendly_tag: $friendly_tag, deployed_by: $deployed_by } } } }' --arg friendly_tag "${FRIENDLY_TAG}" --arg deployed_by "${DEPLOYED_BY}")" \ --context "${KUBECTL_CONTEXT}" \ -n "${ENVIRONMENT}"
这种写法的优势:
- JSON结构保留缩进,可读性强
- 用
jq的--arg注入变量,完全不需要转义引号 - 无需额外临时变量,直接将
jq输出作为--patch参数
方法二:临时文件(适配多JSON参数场景)
如果需要传递多个JSON参数,临时文件能避免变量混乱,逻辑更清晰:
# 生成第一个JSON参数文件 jq -n '{ spec: { template: { metadata: { annotations: { friendly_tag: $friendly_tag, deployed_by: $deployed_by } } } }' --arg friendly_tag "${FRIENDLY_TAG}" --arg deployed_by "${DEPLOYED_BY}" > /tmp/patch1.json # 生成第二个JSON参数文件(示例) jq -n '{ spec: { replicas: $replica_count }' --arg replica_count "${REPLICA_COUNT}" > /tmp/patch2.json # 传递多个JSON参数(kubectl的--patch-file支持多文件) kubectl patch deployment "${APP_NAME}" \ --patch-file /tmp/patch1.json \ --patch-file /tmp/patch2.json \ --context "${KUBECTL_CONTEXT}" \ -n "${ENVIRONMENT}" # 清理临时文件 rm /tmp/patch1.json /tmp/patch2.json
方法三:Here字符串(紧凑版)
如果JSON结构不复杂,也可以用Here字符串替代Heredoc,写法更紧凑:
kubectl patch deployment "${APP_NAME}" \ --patch="$(jq -R -s '.' <<< '{ "spec": { "template": { "metadata": { "annotations": { "friendly_tag": "'"${FRIENDLY_TAG}"'", "deployed_by": "'"${DEPLOYED_BY}"'" } } } } ')" \ --context "${KUBECTL_CONTEXT}" \ -n "${ENVIRONMENT}"
注意变量用'"${VAR}"'包裹,既实现变量替换,又能保留JSON的引号格式。
3. 多JSON参数的Heredoc处理
如果要用Heredoc传递多个JSON,只需生成多个变量分别存储即可:
PATCH1=$(jq -n '{ spec: { template: { metadata: { annotations: { friendly_tag: $friendly_tag, deployed_by: $deployed_by } } } }' --arg friendly_tag "${FRIENDLY_TAG}" --arg deployed_by "${DEPLOYED_BY}") PATCH2=$(jq -n '{ spec: { replicas: $replica_count }' --arg replica_count "${REPLICA_COUNT}") kubectl patch deployment "${APP_NAME}" \ --patch="${PATCH1}" \ --patch="${PATCH2}" \ --context "${KUBECTL_CONTEXT}" \ -n "${ENVIRONMENT}"
内容的提问来源于stack exchange,提问作者Cyril Duchon-Doris
相关产品推荐
相关产品推荐

