0

I want to use curl to PUT data. This works:

curl -X PUT --data '{ "xy": [0.6476, 0.2727] }' "http://"

I have a couple of bash variables that I'd like to use in place of the literals:

$key="xy"
$value="[0.6476, 0.2727]"

I've tried replacing the literals with quoted vars, but I get an error 'parameter not available'. I've tried combinations of nested and escaped quotes, but I am not getting anywhere.

5
  • See also this question about building a JSON object from Bash variables. Commented Dec 4, 2019 at 20:05
  • I tried using jq to build the JSON, but I couldn't get it to work with the array (value). -arg worked for the key, but not for the value. I tried -argjson and that rejected it. Commented Dec 4, 2019 at 20:08
  • Something like this maybe. Commented Dec 4, 2019 at 20:26
  • See stackoverflow.com/questions/59153051/…; it uses a new feature in jq 1.6 for accessing positional arguments to jq as a list. Commented Dec 4, 2019 at 20:35
  • Thank you both. I suspect my problem came from further up the command chain (how the value got assigned to the array variable, which was not as clear cut as I showed) but I got diverted by the failure in curl Commented Dec 4, 2019 at 20:39

3 Answers 3

1

Well this works for me :

 $ key='foo' 
 $ value='[ bar, bar ]' 
 $ echo "{ \"$key\": $value }"
 { "foo": [ bar, bar ] }

So this should work for you as well :

curl -X PUT --data "{ \"$key\": $value }" "http://google.com.uy"

Let me know if it helps!

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. It does work now. I thought I'd tried that combination, but obviously not!
This is a bad idea. It assumes that neither key nor value contain any characters that need to be quoted in a valid JSON value.
1

This works for me with Node:

key="xy"
value="[0.6476, 0.2727]"
jsonData=$(node -e "console.log(JSON.stringify({$key: $value}))")
#jsonData output is: {"xy":[0.6476,0.2727]}

curl -X PUT --data $jsonData "http://"

But this only works for Node.js Developer or you have Node environment installed.

Comments

0

Using jq (1.6 or later), use the --jsonargs option to take multiple JSON-encoded values as a JSON array accessible via $ARGS.positional:

$ key=xy
$ value=(0.6476 0.2727)
$ jq -n '{($k): $ARGS.positional}' --arg k "$key" --jsonargs "${value[@]}"
{
  "xy": [
    0.6476,
    0.2727
  ]
}

--jsonargs must come last, so that all remaining arguments are treated as values in the desired array. We use --jsonargs rather than --args so that you get an array of floating-point values, rather than an array of strings.

Once you have jq working, you pipe its output to curl, which uses - as the argument to --data to read the data from the pipe.

jq -n '{($k): $ARGS.positional}' --arg k "$key" --jsonargs "${value[@]}" |
   curl -X PUT --data - "http://"

3 Comments

Could you explain this a little please. It looks like just what I'm after, but I'm not really sure what '{($k): $ARGS.positional}' is doing.
The parentheses are required to force $k to be evaluated as an expression, rather than an ill-formed literal key. $ARGS.positional is an expression that evaluates to an array containing all the arguments that follow the --args option.
My value is set to a string containing the array I need to send (per my question), so my jsonargs part is --jsonargs "[nnn, nnn]" which is outputting [[nnn nnn]]. How can I get rid of that extra pair of square brackets please?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.