提问人:Cyril Duchon-Doris 提问时间:4/27/2023 最后编辑:Cyril Duchon-Doris 更新时间:4/27/2023 访问量:30
在 shell 脚本参数中以开发人员友好的方式编写 JSON
Write JSON in developer-friendly fashion in shell script arguments
问:
我有一个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}"
}
}
}
}
有没有办法在不使用其他变量的情况下保留这样的语法?否则,我该如何在保持开发人员友好性的同时编写我的 shellscript?
我知道我可以使用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}
答:
2赞
Charles Duffy
4/27/2023
#1
在你进入友好状态之前,对正确性有更大的担忧。要解决这些问题,请考虑:
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 引用来引用环境变量可以避免使用 to 将参数传递到 jq 的仪式。
env
--arg
- 带有文字引号、制表符、换行符、反斜杠或其他 jq 语法的标记(或deployed_by值)将被正确转义,而不是能够将任意 JSON 内容注入输出文档(或者,如果发生错误而不是恶意活动,而不是使该输出不再有效 JSON)。
评论
0赞
Cyril Duchon-Doris
4/27/2023
感谢您的完整答案和警告!非常感谢。
0赞
Ivan
4/27/2023
如果由于拼写错误或拼写错误而返回错误怎么办?猜猜先创建 var 并检查它是否正确,然后再做补丁更安全。jq
0赞
Cyril Duchon-Doris
4/27/2023
您能解释一下如何使用 curl 数据二进制吗?在我之前的脚本中,我使用了 .我不确定我是否可以在那里以同样的方式使用 jq......(对不起,如果它跑题了)curl -X POST -H 'Content-type: application/json' \ --data-binary @- << JSON ${SLACK_WEBHOOK} {...} JSON
0赞
Charles Duffy
4/27/2023
@Ivan、拼写错误或错别字在哪里?在代码中?这就是测试的目的。它不会关心数据的问题;在环境变量中有效的任何数据都可以转换为 JSON 字符串,也可以将某些无效的值转换为 JSON(NUL 在环境变量中是不可能的,但可以在 JSON 字符串中转换为 NUAL)。\u0000
1赞
Charles Duffy
4/27/2023
@CyrilDuchon-Doris,假设你有一个带有 ksh93 扩展的 shell(也存在于 bash 和 zsh 中),;而如果您仅保证 POSIX 合规性,.也可以使用 ,然后是包含 JQ 表达式的行,然后是 ,然后是 (根据需要替换 sigil)。--data-binary @- < <(jq -n '...')
jq -n '...' | curl ... --data-binary @-
--data-binary @- <<EOF
$(jq -n '
')
EOF
评论
${APP_NAME}
"${APP_NAME}"
"$APP_NAME"