在curl命令的JSON负载中展开变量

在curl命令的JSON负载中展开变量

我有一个使用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/shshell,使用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

我无法针对实际的卷曲调用对此进行测试,因此我只是回显结果命令。我相信这至少应该让你成功一半。

相关内容