I have a bash script calling curl, and I want to pass a certain argument only if some condition is fulfilled:
result=$( curl -sS --retry 3 --retry-delay 10 \
# some more stuff
$([[ $b=="b" ]] && echo -F \"foo=bar\") \
"https://www.someurl.org")
For some reason the effect is as if I just do:
result=$( curl -sS --retry 3 --retry-delay 10 \
# some more stuff
"https://www.someurl.org")
How can find out what's wrong? I have tried
result=$( echo -sS --retry 3 --retry-delay 10 \
$([[ $b=="b" ]] && echo -F \"foo=bar\") \
"https://www.someurl.org")
echo result
And -F "foo=bar"
is there all right.
But why does it not seem to effect my curl call?
Trying to generate arguments with a command substitution -- that is, a $( )
expression -- doesn't really work, because the shell parses quotes and escapes before it does the command substitution. This means that quotes and escapes in the command's output don't get fully parsed by the shell, they're just passed on as literal parts of the data. So in your example, you're sending a form field named "foo
(including a literal double-quote) with the value bar"
(again, a literal quote). If the field value contained any whitespace, it'd be even worse, because the shell does word splitting on the command-substituted value, in spite of any quotes it contains.
So how can you do this? The most general way is to compute the conditional arguments in advance, and store them in an array:
extraArgs=()
if [[ $b == "b" ]]; then # Note: the spaces around == are required
extraArgs+=(-F "foo=bar")
fi
result=$( curl -sS --retry 3 --retry-delay 10 \
"${extraArgs[@]}" \
"https://www.someurl.org")
In the special case where you want to pass conditional arguments if a variable is set to a non-empty value, you can do it directly in the command line:
fooValue=something
result=$( curl -sS --retry 3 --retry-delay 10 \
${fooValue:+ -F "foo=$fooValue"} \
"https://www.someurl.org")
The ${variable:+something}
expansion tells bash to include something
in the command only if variable
is set and has a non-null value. In this case, the quoting in something
section is parsed and respected by the shell. BTW, this method should work even in shells that don't support arrays (e.g. dash).