我有一个使用curl 发送post 请求的shell 脚本。
#!/bin/sh
NEXT_JOB_COMMANDS='["sleep", "200s"]'
STATUS="successful"
if [ "$STATUS" = "successful" ]
then
NEXT_JOB_ID=$(curl -s "localhost:5050/processes/gdalEcho/execution" \
--header 'Content-Type: application/json' \
--data '{
"commandOverride": ["sleep", "200s"]
}')
echo "$NEXT_JOB_ID"
fi
它运行良好,直到我尝试["sleep", "200s"]
用NEXT_JOB_COMMANDS
变量替换。如何在curl的JSON负载中扩展变量?
NEXT_JOB_COMMANDS='["sleep", "200s"]'
STATUS="successful"
if [ "$STATUS" = "successful" ]
then
NEXT_JOB_ID=$(curl -s "localhost:5050/processes/gdalEcho/execution" \
--header 'Content-Type: application/json' \
--data '{
"commandOverride": ' "$NEXT_JOB_COMMANDS" '
}')
echo "$NEXT_JOB_ID"
fi
答案1
您的主要问题实际上是代码中这些行上的几个空格字符:
--data '{
"commandOverride": ' "$NEXT_JOB_COMMANDS" '
}')
第二个单引号脱离了单引号字符串,它是 选项--data
的选项参数curl
。单引号后面的空格字符确保字符串 in$NEXT_JOB_COMMANDS
将是有自己的论据到curl
,然后添加}
(前面有换行符)作为额外的参数,这可能会curl
更加令人困惑。
你可以通过将中间线更改为来解决此问题
"commandOverride": '"$NEXT_JOB_COMMANDS"'
...但您也可以使用jq
将$NEXT_JOB_COMMANDS
值插入表单主体(这将确保生成的 JSON 主体格式正确且有效)。
--data
如果您想将格式良好的 JSON 文档(您的数组)作为调用中使用的 JSON 文档中的顶级键传递curl
,您可以执行以下操作:
NEXT_JOB_COMMANDS='["sleep", "200s"]'
NEXT_JOB_ID=$(
formdata=$( jq -c -n --argjson commandOverride "$NEXT_JOB_COMMANDS" '$ARGS.named' ) &&
curl -s \
--header 'Content-Type: application/json' \
--data "$formdata" \
'http://localhost:5050/processes/gdalEcho/execution'
)
printf '%s\n' "$NEXT_JOB_ID"
在这里,shell 变量formdata
(对于命令替换来说是本地的)将获取值
{"commandOverride":["sleep","200s"]}
这是使用 来创建的jq
,它将插入给定的 JSON 片段作为键的值commandOverride
。
上述的一个变体允许您完全避免编写 JSON,而是将数组作为数组存储在 shell 中:
NEXT_JOB_COMMANDS=( 'sleep' '200s' )
NEXT_JOB_ID=$(
formdata=$(
jq -c -n '{ commandOverride: $ARGS.positional }' --args "${NEXT_JOB_COMMANDS[@]}"
) &&
curl -s \
--header 'Content-Type: application/json' \
--data "$formdata" \
'http://localhost:5050/processes/gdalEcho/execution'
)
printf '%s\n' "$NEXT_JOB_ID"
上面假设 shell 具有命名数组。对于/bin/sh
shell,使用set -- sleep 200s
将位置参数列表设置为数组元素,然后"$@"
将该列表插入--args
到 的参数后面jq
。
答案2
每当我在 bash 中遇到 json 时,我默认使用 jq,因此以您的脚本为例:
#!/usr/bin/env bash
NEXT_JOB_COMMANDS='["sleep", "200s"]'
STATUS="successful"
if [ "$STATUS" = "successful" ]
then
echo curl -s "localhost:5050/processes/gdalEcho/execution" \
--header 'Content-Type: application/json' --data "$(echo "$NEXT_JOB_COMMANDS" | jq -rc '{"commandOverride":.}')"
echo "$NEXT_JOB_ID"
fi
我无法针对实际的卷曲调用对此进行测试,因此我只是回显结果命令。我相信这至少应该让你成功一半。