在 shell 脚本参数中以开发人员友好的方式编写 JSON

问题描述 投票:0回答:1

我有一个 shellscript,我需要将 JSON 作为函数参数传递

我想编写对开发人员友好的缩进代码,而不是编写难以维护的单行参数,或带有转义换行符和引号的多行参数

我从什么开始

kubectl patch deployment ${APP_NAME} \
      --patch="{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"friendly_tag\":\"${FRIENDLY_TAG}\",\"deployed_by\":\"${DEPLOYED_BY}\"}}}}}" \

我想以什么结尾(下面的例子显然不能在 shell 中运行)

kubectl patch deployment ${APP_NAME} \
      --patch={ 
         "spec": {
              "template": {
                  "metadata": {
                      "annotations": {
                          "friendly_tag": "${FRIENDLY_TAG}",
                          "deployed_by": "${DEPLOYED_BY}"
                      }
                  }
              }
          }

有没有办法在不使用额外变量的情况下保留这样的语法?否则如何在保持开发人员友好性的同时编写我的 shellscripts?

我知道我可以使用 heredocs,但我不太确定如果我有 2 个 JSON 参数传递给我的函数(其他将我的 heredoc 放在变量中并将它们作为参数传递)我可以使用它们

此外,在这种情况下,json 引号需要转义,所以我不确定 heredocs 是否方便。

编辑:我正在谈论的 heredoc 语法(这迫使你有一个未缩进的

JSON
结束标记)

PATCH=$(jq -R -s --raw-output '.' <<-JSON
        {
          "spec": {
            "template": {
              "metadata": {
                "annotations": {
                  "friendly_tag": "${FRIENDLY_TAG}",
                  "deployed_by": "${DEPLOYED_BY}"
                }
              }
            }
          }
        }
JSON
    )
    kubectl patch deployment ${APP_NAME} \
      --patch="${PATCH}" \
      --context ${KUBECTL_CONTEXT} \
      -n ${ENVIRONMENT}
shell pretty-print heredoc
1个回答
2
投票

在你变得友好之前,对正确性有更大的担忧。要解决这些问题,请考虑:

export FRIENDLY_TAG DEPLOYED_BY # variables need to be in the environment

kubectl patch deployment "${APP_NAME}" \
  --patch="$(jq -n '
    { 
      "spec": {
        "template": {
          "metadata": {
            "annotations": {
              "friendly_tag": env.FRIENDLY_TAG,
              "deployed_by": env.DEPLOYED_BY
            }
          }
        }
      }
    }')"

这在不影响正确性的情况下尽可能友好。

  • 在 jq 表达式周围使用单引号确保该表达式中不需要任何额外的反斜杠。
  • 使用 jq
    env
    引用来引用环境变量避免了使用
    --arg
    将参数传递给 jq 的仪式。
  • 带有文字引号、制表符、换行符、反斜杠或其他 jq 语法的标记(或 deployed_by 值)将被正确转义,而不是能够将任意 JSON 内容注入输出文档(或者,如果发生错误而不是恶意的活动——而不是使该输出不再有效 JSON)。
© www.soinside.com 2019 - 2024. All rights reserved.