Scripted concatenation of strings in curl command payload
Asked Answered
N

2

5

I use curl to test an user account creation API as follows:

curl -s -X POST "https://$APISERVER/users" \
-H 'Content-Type: application/json' \
-d '{ \
"username": "'$NEWUSERNAME'", \
"firstName": "'$NEWUSERFIRSTNAME'", \
"lastName": "'$NEWUSERLASTNAME'", \
"displayName": "'$NEWUSERDISPLAYNAME'", \
"password": "'$NEWUSERPASSWORD'" \
}'

and the variables are supplied via command line arguments:

APISERVER=http://localhost:8080
NEWUSERNAME=$1
NEWUSERPASSWORD=$2
NEWUSERFIRSTNAME=$3
NEWUSERLASTNAME=$4

# Calculated variable
NEWUSERDISPLAYNAME="${NEWUSERFIRSTNAME} ${NEWUSERLASTNAME}"

An example invocation of the script is as follows: ./test-new-user.sh jdoe Hello123 John Doe, resulting in the following variable values:

NEWUSERNAME=jdoe
NEWUSERPASSWORD=Hello123
NEWUSERFIRSTNAME=John
NEWUSERLASTNAME=Doe

(I intended NEWUSERDISPLAYNAME to be set to "John Doe")

But I get back an exception from the server, because the payload in the curl command appears to be cut-off, incomplete or malformed.

JSON parse error: Unexpected end-of-input in VALUE_STRING\n at [Source: 
java.io.PushbackInputStream@2eda6052; line: 1, column: 293]; nested 
exception is com.fasterxml.jackson.databind.JsonMappingException: 
Unexpected end-of-input in VALUE_STRING\n at [Source: 
java.io.PushbackInputStream@2eda6052; line: 1, column: 293]\n at 
[Source: java.io.PushbackInputStream@2eda6052; line: 1, column: 142] 
(through reference chain: 
com.mycompany.api.pojos.NewUser[\"displayName\"])"

If I hard code value for displayName in the above curl command (as below), the user creation request goes through and works perfectly.

"displayName": "John Doe", \

I suspect it has to do with the space in displayName and how I insert the value for displayName using "'$NEWUSERDISPLAYNAME'". Is there a safe way to perform variable substitution in the curl command's POST request payload?

Noway answered 30/5, 2018 at 20:39 Comment(0)
P
15

You need to quote shell variables:

curl -s -X POST "https://$APISERVER/users" \
-H 'Content-Type: application/json' \
-d '{ \
"username": "'"$NEWUSERNAME"'", \
"firstName": "'"$NEWUSERFIRSTNAME"'", \
"lastName": "'"$NEWUSERLASTNAME"'", \
"displayName": "'"$NEWUSERDISPLAYNAME"'", \
"password": "'"$NEWUSERPASSWORD"'" \
}'

In order to avoid excessive quoting, try this printf:

printf -v json -- '{ "username": "%s", "firstName": "%s", "lastName": "%s", "displayName": "%s", "password": "%s" }' \
"$NEWUSERNAME" "$NEWUSERFIRSTNAME" "$NEWUSERLASTNAME" "$NEWUSERDISPLAYNAME" "$NEWUSERPASSWORD"

curl -s -X POST "https://$APISERVER/users" \
    -H 'Content-Type: application/json' \
    -d "$json"
Pesade answered 30/5, 2018 at 20:53 Comment(1)
Yes, that worked. Thanks! All the other variables substitute just fine though. It is just this one which has a space in the value. Is there a better way to do this, or use curly braces notation, to make it more readable? Because the use of double-single-double quote wrapping is confusing.Noway
B
-1

just use

$(echo $varname)

works for me

Bestrew answered 29/3, 2022 at 2:31 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Bodrogi

© 2022 - 2024 — McMap. All rights reserved.