Problem:
I'm writing a script that performs several HTTP requests with curl and I want to add the headers to a variable, CURL_HEADERS, so that I don't have to type them out constantly. When I echo the CURL_HEADERS variable in the curl command, single quotations appear where I don't want them. How can I prevent this? (The code below is simplified for the sake of clarity)
Code
#!/usr/bin/env bash
AUTH_KEY='1234'
set -x
CURL_HEADERS='-H "Authorization: Basic '${AUTH_KEY}'" -H "Content-Type: application/json"'
echo "${CURL_HEADERS}"
curl -s $(echo "${CURL_HEADERS}") 'http://www.example.org' > /dev/null
set +x
Expected Output:
+ CURL_HEADERS='-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
-H "Authorization: Basic 1234" -H "Content-Type: application/json"
++ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ curl -s -H "Authorization: Basic 1234" -H "Content-Type: application/json" http://www.example.org
+ set +x
Actual Output
+ CURL_HEADERS='-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
-H "Authorization: Basic 1234" -H "Content-Type: application/json"
++ echo '-H "Authorization: Basic 1234" -H "Content-Type: application/json"'
+ curl -s -H '"Authorization:' Basic '1234"' -H '"Content-Type:' 'application/json"' http://www.example.org
+ set +x
A reasonably straightforward solution is to use a bash array to store the four arguments you will want to pass:
CURL_HEADERS=(
'-H' "Authorization: Basic ${AUTH_KEY}"
'-H' 'Content-Type: application/json'
)
curl -s "${CURL_HEADERS[#]}" 'http://www.example.org' > /dev/null
Unlike scalar variables, which are just ordinary strings of ordinary characters no matter how many quotes they might contain, arrays are lists of strings, each one distinguished from each other one. In this sense, bash is just like almost every other programming language.
This problem, and the solution I suggest as well as several other ones, is well-described in the Bash FAQ entry 50 (I'm trying to put a command in a variable, but the complex cases always fail!), which is worth reading in detail. (Link taken from a comment by #John1024.)
The proposed array is a good design approach, but curl still adds single quotes to the array items that already contain double quotes around them, thus making invalid headers.
Related
I looked at all previous answers on this subject but just can't get my POST request to work in cURL windows although it works perfectly in PostMan. I exported the code using </> and tried several combinations of export parameters... any help would greatly appreciated!
Here's my cURL code:
curl -L -X POST "https://timingserver.net/api/bridge/generic" -H "cache-control: no-cache" -H "connection: close" -H "content-type: application/json" --data-raw "{
\"username\":\"myusername\",
\"password\":\"mypassword\",
\"event\":\"demo\",
\"checkpoint\":12,
\"detections\":[{\"bib\":100, \"dt\":\"2022-01-12T13:09:23.045\"},
{\"bib\":101, \"dt\":\"2022-01-12T13:09:23.045\"},
{\"bib\":102, \"dt\":\"2022-01-12T13:09:23.045\"},
{\"bib\":199, \"dt\":\"2022-01-12T13:10:23.045\"}]
}"
Getting several errors in the same execution: Code 400, not recognized as an internal or external command... cannot find the path specified...
You need to remove the linebreaks:
curl -L -X POST "https://timingserver.net/api/bridge/generic" -H "cache-control: no-cache" -H "connection: close" -H "content-type: application/json" --data-raw "{ \"username\":\"myusername\", \"password\":\"mypassword\", \"event\":\"demo\", \"checkpoint\":12, \"detections\":[{\"bib\":100, \"dt\":\"2022-01-12T13:09:23.045\"}, {\"bib\":101, \"dt\":\"2022-01-12T13:09:23.045\"}, {\"bib\":102, \"dt\":\"2022-01-12T13:09:23.045\"}, {\"bib\":199, \"dt\":\"2022-01-12T13:10:23.045\"}] }"
To generate curl output for windows using postman click on settings next to curl code section and change line continuation character to ^ and quote double and shown in the image. This should generate output for windows. You can also change the output to single or multiline.
I'm trying to create a Jelastic Manifest with a cURL command inside it. When I import it, it gives me an error but unfortunately I have no access to the console (disabled by the provider).
The command is the following :
curl -X POST <my_url> -H "Content-Type: application/json" -H "Authorization: Bearer <token>" -d "{}"
Some additionnal information :
The URL is correct 100%
The token does not contain any special characters : Only upper/lowercase characters and numbers
The command is run successfully from the command line
If I remove the first -H parameter, I can import my manifest. Same if I remove the second -H parameter and keep the first one
My guess is that, somehow, having two -H is not considered as valid but I don't know why. Any ideas ?
EDIT : A screenshot of the error shown on the platform
The "two -H parameters" wasn't a root cause in your question.
The thing is that the YAML gets the data you sent as a key/value array (dictionary).
In your example it would be:
curl -s -X POST https://test.com -H "Content-Type - as a key,
and
application/json" -H "Authorization: Bearer xx" -d "{\"Key\":\"Value\"}" - as a value.
If you need an array of strings the YAML may be as this
cmd [cp]:
- 'curl -s -X POST https://test.com -H "Content-Type: application/json" -H "Authorization: Bearer xx" -d "{\"Key\":\"Value\"}"'
If you need a multi-line string it should look like this
cmd [cp]: |
curl -s -X POST https://test.com -H "Content-Type: application/json" -H "Authorization: Bearer xx" -d "{\"Key\":\"Value\"}"
I am using AWX curl for update template in bash script. Somehow this curl command is not able to run
curl --insecure -v -X PATCH https://somedomain.corp.com/api/v2/job_templates/\"$test_2_template\"/ -H 'Authorization: Basic keys==' -H 'Content-Type: application/json' -d '{"extra_vars":"{\"module_name\": \"$module_name\", \"env\": \"$appenv\", \"host_group_name\": \"$host_group_name\", \"rolename\": \"$rolename\", \"app_artifact_url\": \"$app_artifact_url\"}"}'
Looks like there is some issue in passing variables to curl command via bash
However if i run this from my terminal , it's working fine.
curl --insecure -v -X PATCH https://somedomain.com/api/v2/job_templates/279/ -H 'Authorization: Basic keys==' -H 'Content-Type: application/json' -d '{"extra_vars":"{\"module_name\": \"myservice\", \"env\": \"test\", \"host_group_name\": \"env2\", \"rolename\": \"myservice\", \"artifact_version\": \"2.1.0-SNAPSHOT\"}"}'
Please suggest some solution.
You can't substitute variables inside a single quoted string.
For terrible long commands like this, breaking them up into pieces is essential for readability and maintainability:
data=$(printf \
'{"extra_vars": "{\"module_name\": \"%s\", \"env\": \"%s\", \"host_group_name\": \"%s\", \"rolename\": \"%s\", \"app_artifact_url\": \"%s\"}"}' \
"$module_name" "$appenv" "$host_group_name" "$rolename" "$app_artifact_url"
)
curl_args=(
--insecure
-v
-X PATCH
-H 'Authorization: Basic keys=='
-H 'Content-Type: application/json'
-d "$data"
)
url="https://somedomain.example.com/api/v2/job_templates/$test_2_template/"
curl "${curl_args[#]}" "$url"
I have a simple bash script that call cURL with several params.
I need to write the output in a file (also overwriting). But I cannot do.
The call itself works, but I have only an empty file (and the answer is a json, I can read on the shell with that echo)
Thank you in advance for your help
1st try
curl -X POST "https://www.example.com"\
-H "X-Auth-Email: $email"\
-H "X-Auth-Key: $auth_key"\
-H "Content-Type: application/json"\
--data '{"name":"'$name'","surname":"'$surname'"}'
>> id.txt
echo
2nd try
curl -X POST "https://www.example.com"\
-H "X-Auth-Email: $email"\
-H "X-Auth-Key: $auth_key"\
-H "Content-Type: application/json"\
--data '{"name":"'$name'","surname":"'$surname'"}'
o id.txt
echo
curl -X POST "https://www.example.com"\
-H "X-Auth-Email: $email"\
-H "X-Auth-Key: $auth_key"\
-H "Content-Type: application/json"\
--data '{"name":"'$name'","surname":"'$surname'"}'\
-o id.txt
I have the following cURL request. I want to get the http_code, but I want in a different variable, because otherwise it messes with parsing the JSON response from the GET call.
Is there anyway to do this?
curl --write-out %{http_code} --silent --output GET --header "Accept: application/json" --header "URL"
Just use command substitution to store status code in a variable:
status=$(curl --write-out %{http_code} --silent --output tmp.out GET --header "Accept: application/json" --header "URL")
data=$(<tmp.out)
# check status now
declare -p status
# check data
declare -p data
curl -i -H "Accept: application/json" "server:5050/a/c/getName{"param0":"Arvind "}"
curl -w 'RESP_CODE:%{response_code}' -s -X POST --data '{"asda":"asd"}' http://example.com --header "Content-Type:application/json"|grep -o 'RESP_CODE:[1-4][0-9][0-9]'
response=$(curl -sb -H "Accept: application/json" "http://host:8080/some/resource") For response just try $response
Try this following may be this could help you to find the solution https://gist.github.com/sgykfjsm/1dd9a8eee1f70a7068c9