When i input a variable on the curl with the json indexed, it takes the string value of the variable, if i scaped the double-quotes, it returns me a sintax error because of in a json request u have to input the data with double-quotes. Example:
#!/bin/bash
token="x"
tokenPass="x"
name="prueba"
url="https://prueba.prueba.prueba"
user="prueba"
pass="prueba"
notes="prueba"
curl -k -H "Content-Type:Application/json" -d '{"jsonrpc": "2.0", "method": "account/create", "params": { "authToken": "$token", "tokenPass": "$tokenPass", "name": "$name" , "categoryId": "7", "clientId": "9","login":"$user","url": "$url" ,"pass": "$pass","notes": "$notes"}, "id": 1}' -o- https://syspass.prueba.es/api.php
The curl json request works if i input the data manually, but with the variables, when i create the account, the account is named as the string value of the variable, i mean, if the variable is named $name , the account created is name $name. Any help please? Also i tried to input the variable: "${variable}" and either works
CodePudding user response:
Try this:
curl -k -H "Content-Type:Application/json" -d '{"jsonrpc": "2.0", "method": "account/create", "params": { "authToken": "'${token}'", "tokenPass": "'${tokenPass}'", "name": "'${name}'" , "categoryId": "7", "clientId": "9","login":"'${user}'","url": "'${url}'" ,"pass": "'${pass}'","notes": "'${notes}'"}, "id": 1}' -o- https://syspass.prueba.es/api.php
A bit of explanation:
Text that is between single quotes '
will not be interpreted by bash and that is why the variables will not be inserted. You have to break the string up...
An other suggestion is that you should use curly braces around variables: When do we need curly braces around shell variables?
CodePudding user response:
I explain it here for the variable token. The other variables can be treated in the same way.
Assuming that the variable token contains the string foo bar baz, then you want curl
to receive as its 5th argument the following string:
{"jsonrpc": "2.0", "method": "account/create", "params": { "authToken": "foo bar baz", "tokenPass":... rest omitted for brevity}
Since this has to become a single argument, you have to quote the hole string somehow, and because this string contains many double-quotes, it is easier to use single quotes for wrapping. However, this would prevent parameter expansion. To make this happen, the variables must be outside the single quotes. However, they must also be inside double quotes, lest you become a victim of word splitting, if the variables contain spaces. This yields the following solution:
curl .... '{"jsonrpc": "2.0", "method": "account/create", "params": { "authToken": "'"$token"'", "tokenPass": ... rest omitted for brevity}'
Note the "'"
in front of $token
: The first double quote is the one which will be part of the expanded "foo bar baz"
. It must be literal, because curl wants to see it. The next single quote terminates the initial single quote. The next double quote tells the shell to expand $token
, but without attempting word splitting.
If there are many parameters to expand, the resulting expression is difficult to debug and maintain. An alternative is to set up a HERE-document:
# Set up Parameter 5 for curl
read p5 <<END
{"jsonrpc": "2.0", "method": "account/create", "params": { "authToken": "$token", "tokenPass":... rest omitted for brevity}
END
and then use it as
curl .... -d "$p5"
This requires the separated step of setting up the argument, but in the end is much more readable, and you don't have to worry about word splitting either.
CodePudding user response:
I'd use jq
to generate the JSON string (mostly, to handle the quoting for you, JSON strings are not trivial), and for readability (and for the sanity of the next maintainer) add some newlines and indentation:
data=$(
jq -n \
--arg token "$token" \
--arg tokenPass "$tokenPass" \
--arg name "$name" \
--arg url "$url" \
--arg user "$user" \
--arg pass "$pass" \
--arg notes "$notes" \
'{
jsonrpc: "2.0",
method: "account/create",
params: {
authToken: $token,
tokenPass: $tokenPass,
name: $name,
categoryId: "7",
clientId: "9",
login: $user,
url: $url ,
pass: $pass,
notes: $notes
},
id: 1
}'
)
curl -k \
-H "Content-Type:Application/json" \
-d "$data" \
-o- \
https://syspass.prueba.es/api.php