Score:7

Bash variable in 2 quotes

pl flag

I want to send a request like this with curl:

curl some parameters and headers --data-binary '{"secret":"$1"}'

but $1 is not being variable. I tried using echo with this command:

echo '{"asd":"$1"}' dhkdgb

and I got this output:

{"asd":"$1"} dhkdgb

However, I want to get this output:

{"asd":"dhkdgb"}

And at curl request, I want to send this:

curl some parameters and headers --data-binary '{"secret":"argv 0 of script"}'

How can I solve this issue?

ar flag
$1 is a variable containing the first argument to your script... but you don't use a script, right? You just type the curl command at the prompt? So $1 is empty/unset. Also, variables inside single quotes are not interpreted. You would use single quotes if you want to use "$1" literally, without Bash interpreting it as a variable.
ar flag
If you do call this from a script and `$1` is indeed defined, then replace your single quotes with double quotes and your double quotes with either single quotes or escaped double quotes. Replace `'{"secret":"$1"}'` with `"{\"secret\":\"$1\"}"` or with `"{'secret':'$1'}"`
in flag
@mivk The official JSON spec actually requires double quotes for strings (both in keys and values), so for it to be properly portable you would have to use escaped double quotes instead of the single quote approach.
Score:11
hr flag

There are several ways to do it ex. given

$ set -- 'foo bar'

(to assign value foo bar to the shell's first positional parameter, as if in a script invoked like myscript "foo bar") then for example

$ echo '{"asd:":"'"$1"'"}'
{"asd:":"foo bar"}

or

$ echo {\"asd:\":\""$1"\"}
{"asd:":"foo bar"}

However you may find it cleaner to use the shell's printf builtin to create a formatted string that you can assign to a new variable:

$ printf -v data '{"asd": "%s"}' "$1"
$ echo "$data"
{"asd": "foo bar"}

which you can then use as

curl some parameters and headers --data-binary "$data"

Alternatively, since you appear to be trying to pass a JSON object to the curl command, you could consider using jq in place of printf:

$ jq -nc --arg x "$1" '{asd: $x}'
{"asd":"foo bar"}

or similarly using the built-in $ARGS array

$ jq -nc --arg asd "$1" '$ARGS.named'
{"asd":"foo bar"}

if you want to pass both the name and value to the constructor.

muru avatar
us flag
`jq` has a nicer way of doing this: `jq -n --arg asd "$1" '.$ARGS.named'`
vanadium avatar
cn flag
Unless I missed something, I think this is much easier to solve - see my answer.
hr flag
@vanadium - sure, as I mentioned there are several ways to do it with esacpes. I just happen not to be a fan of "leaning toothpicks" so tried to offer some alternatives
hr flag
@muru that's nice - thanks. Added.
Score:0
in flag

I tend to use a heredoc and -d@- (read input data from stdin) for composing JSON request bodies:

cat <<EOF |
{
    "secret": "$SECRET"
}
EOF
curl ... \
    -X POST \
    -H "Content-Type: application/json" \
    "${BASE_URL%%/}/the/path" -d@-

Yes, the syntax is a little weird.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.