-1

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

forzax hx
  • 3
  • 2
  • Your i.e. `$token` is between single quotes and therefore not expanded. The single quote opens after `-d` and ends before the `-o`. – user1934428 Nov 17 '21 at 11:17
  • it must be like that, instead returns syntax error – forzax hx Nov 17 '21 at 11:24
  • I just explained why you get the effect which you obsered. I didn't say that you should not use single quotes at all, if you want to hold it together as a single argument. You just have to glue together the parts which need different quoting, i.e. `' This is not expanded'"$token"' this is not expanded either'` would just expand _token_ and still yield a single argument. This is not related to json, but general _bash quoting_ rules. – user1934428 Nov 17 '21 at 13:11

3 Answers3

0

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?

Swifty
  • 180
  • 7
  • thanks, it is working now, thanks – forzax hx Nov 17 '21 at 11:38
  • Okey, i fix that part but with this solution, when i try to input a .csv file with double-quotes it returns syntax error(this if because the value of the variable of the csv in interpreted with the quotes, instead without them. for the json is inputted ""data"", instead of "data", and it returns a syntax error), without double-quotes it returns "encode error" and with sigle-quotes the same as with double-quotes. @Swifty – forzax hx Nov 17 '21 at 12:32
  • @Swifty: Not knowing what's inside _token_, I would put `$token` between double quotes, to avoid word splitting on white space. No need for curly braces here. – user1934428 Nov 17 '21 at 13:12
  • the csv for the account/create API script is somethink like "data","data","data",......... When i input this on the API script it return me a Syntax Error caused of a double double-quotes, the double-quotes of the api Script and de double-quotes of the csv, if i write the csv like data,data,data,......... ir return a Encode Error caused by a data type error – forzax hx Nov 17 '21 at 14:12
0

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.

user1934428
  • 19,864
  • 7
  • 42
  • 87
0

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
glenn jackman
  • 238,783
  • 38
  • 220
  • 352