0

I'm trying to pass arguments in a variable to curl and it fails. I turned on set -x to get more information, and I'm really confused about all the single quotes I'm seeing here.

curlopts="-ksS -H 'Content-Type:application/x-www-form-urlencoded'"

$ curl "$curlopts" https://localhost
+ curl '-ksS -H '\''Content-Type:application/x-www-form-urlencoded'\''' https://localhost
curl: option -ksS -H 'Content-Type:application/x-www-form-urlencoded': is unknown
curl: try 'curl --help' or 'curl --manual' for more information

It works without quotes like curl $curlopts https://localhost but I thought it's generally bad practice to use a variable without quotes.

Elliott B
  • 980
  • 9
  • 32
  • 1
    As you see in the -x output, quoting means the entire variable is passed as one argument. However, curl expects each to be separate. – MisterMiyagi Oct 22 '19 at 06:07

1 Answers1

1

This:

curlopts="-ksS -H 'Content-Type:application/x-www-form-urlencoded'"

sets curlopts to -ksS -H 'Content-Type:application/x-www-form-urlencoded'.

After the above, this:

curl "$curlopts" https://localhost

is equivalent to this:

curl "-ksS -H 'Content-Type:application/x-www-form-urlencoded'" https://localhost

meaning that it calls curl with two arguments: -ksS -H 'Content-Type:application/x-www-form-urlencoded', and https://localhost.

But of course, you want to call curl with four arguments: -ksS, -H, Content-Type:application/x-www-form-urlencoded, and https://localhost.

To achieve that, I recommend using an array:

curlopts=(-ksS -H Content-Type:application/x-www-form-urlencoded)

curl "${curlopts[@]}" https://localhost

where the "${arrayname[@]}" syntax expands, magically, into a separate double-quoted word for each element of the array.

(Note: I've removed the single-quotes because they aren't needed here — none of the characters in Content-Type:application/x-www-form-urlencoded require quoting — but if they make you feel happier, you can safely re-add them.)

ruakh
  • 175,680
  • 26
  • 273
  • 307