14

I have a curl command that sends a string of text to the server and I've been trying to figure out how to either have the string of text come from a file or from a bash variable. The command looks like this:

curl -X POST -u "apikey:<apikey>"
--header "Content-Type: application/json"
--data '{"text": "<variable>"}'
"<url>"

I can't figure out how to get a variable in there. I've tried replacing with $variable and $(< file) but I don't know how to get those to spit out text without an echo and I can't echo in a curl.

4 Answers 4

18

Stop the single quoted string, follow with the variable expansion, posibly double quoted, and resume the single quoted string:

--data '{"text": "'"$variable"'"}'

($variable should still expand to something that together with the surroundings forms legal JSON, or else the other side probably won't be very happy :) .)

If "$variable" can contain JSON special symbols, you'll need to escape them first -- see Kusalanda's more generic answer for that.

1
  • 1
    @NelloDraws It will not work if the value in $variable contains characters that need to be encoded in JSON strings, such as double quotes, tabs, and newlines.
    – Kusalananda
    Jun 1, 2023 at 19:41
4

Just to put one more solution here:

curl -X POST -u "apikey:${apikey}"
--header "Content-Type: application/json"
--data "{\"text\": \"${variable}\"}"
"${url}"

Basically, " is a quote to handle the following string together, \" escapes the quote, and ${varname} is a variable.

4

I tend to use heredocs when building JSON for use with curl:

curl -s -X POST $URL -d@- <<EOF
[
    {
        "id": 101,
        "text": "$variable"
    }
]
EOF
1

Assuming you want to create a JSON document with an arbitrary string, this string must be properly quoted and JSON encoded (a variety of characters are not allowed as literals in JSON strings and must be either escaped or replaced with encodings). The easiest way to do this is with a JSON-aware tool such as jq or jo:

Using jq (this creates an object with each key+value pair specified using --arg key value on the command line; use --argjson key value for values that are not strings):

jq -nc --arg text "$variable" '$ARGS.named'

Using jo (this creates an object with the keys and values given as =-delimited pairs on the command line; the type of the value will be inferred by jo (see the manual)):

jo text="$variable"

With either of the two command above, posting the resulting JSON document could be done in a pipeline like so:

json-generating-command |
curl --silent --show-error \
    --user "apikey:$apikey" \
    --json @- "$url"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .