How can I pass all arguments to another command, some of which are quoted and contain spaces? - bash

I want to pass multiple arguments through to curl. Some of these arguments are quoted and contain spaces.
I have tried like this:
ARGS="http://example.org -H 'My-Header: Foo'"
curl -vvv $ARGS
But my header is not set and I get an error at the end curl: (6) Could not resolve host: Foo'.
I have also tried quoting ARGS like this:
ARGS="http://example.org -H 'My-Header: Foo'"
curl -vvv "$ARGS"
But I get curl: (3) URL using bad/illegal format or missing URL.
If I just run curl with the arguments directly, then it works fine:
curl -vvv http://example.org -H 'My-Header: Foo'
How can I pass these arguments through to curl correctly?

There is a command called eval which evaluates all the arguments into one string and then runs it as a one big command.
Try eval curl $ARGS
I recommend you to checkout eval's man page ;)

Related

How i can safe the curl result in a bash variable

When i run the command
curl -d "param1=value1&param2=value2" -X POST https://xxx.xxxx.de/xx/xx.php 2>/dev/null on the normal command line i get the requested result {"success":false,"cause":"Token needed"}.
I need this result on a bash script but when i try to run it
curl = "$(curl -d "param1=value1&param2=value2" -X POST https://xxx.xxxx.de/xx/xx.php 2>/dev/null)"
echo $curl
I don't recieve the requested result i recieve this
[1/2]: "success":false --> <stdout>
--_curl_--"success":false
curl: (3) URL using bad/illegal format or missing URL
[2/2]: "cause":"Token needed" --> <stdout>
--_curl_--"cause":"Token needed"
curl: (3) URL using bad/illegal format or missing URL
How i can use the correct result in my bash script ?
Your command is not a variable assignment, it tries to executes curl with arguments = and the output of the command substitution. Remove the space characters before and after = and you may omit the quotes around the command substitution (this is one of the few occasions where quotes are not needed).
curl=$(curl -d "param1=value1&param2=value2" -X POST https://xxx.xxxx.de/xx/xx.php 2>/dev/null)
echo "$curl"

How to retrieve error code from cURL on shell

I know a similar question was posted, but I can't get it to work on my machine.
I tried the 1st answer from the mentioned question, i.e. response=$(curl --write-out %{http_code} --silent --output /dev/null servername) and when I echo $response I got 000 [Not sure if that is the desired output].
However, when trying to do so with my cURL command, I get no output.
This is my command:
curl -k --silent --ftp-pasv --ftp-ssl --user C:is_for_cookies --cert localcert_cert.pem --key certs/localcert_pkey.pem ftps://10.10.10.10:21/my_file.txt
and I use it with
x=$(curl -k --silent --ftp-pasv --ftp-ssl --user C:is_for_cookies --cert localcert_cert.pem --key certs/localcert_pkey.pem ftps://10.10.10.10:21/my_file.txt)
but when I try to echo $x all I get is a newline...
I know the cURL is failing, because when I run the same command, without --silent, I get curl: (7) Couldn't connect to server
This Q is tagged with both sh, bash because I've tried it on both with same results
I found this option which kind of helps (but I still don't know how to assign it to a variable, which should be easier than this...):
--stderr <file>
Redirect all writes to stderr to the specified file instead. If the file name is a plain '-', it is instead written to stdout.
If this option is used several times, the last one will be used.
When I use it like this:
curl -k --silent -S --stderr my_err_file --ftp-pasv --ftp-ssl --user C:is_for_cookies --cert localcert_cert.pem --key certs/localcert_pkey.pem ftps://10.10.10.10:21/my_file.txt
I can see the errors (i.e. curl: (7) Couldn't connect to server) inside that file.
I used --silent to suppress all output, and -S to un-suppress the errors, and the --stderr <file> to redirect them

Quoting of arguments passed to Curl command in Script file

I have been trying to execute curl command from a script file.
The command is as follows (the IP address is stored in variable ip):
curl -s -X POST ${ip1} -H \"content-type: application/json\" -d \''{"args":["org1","scatest'$j$i'","27-06-2018"]}'\'
It's throwing an error saying "cannot read property", if I execute from the script file.
Whereas if I execute from the command line then there is no problem.
Can anybody help me out why curl command is not getting executed from the script file?
Since the discussions under the comment has lead to a solution that works well. I'm gonna put it into answer for the record and in case anyone else runs into the same pitfall.
The problem was caused by excessive quoting which would result in extra quotes being made part of the request, correct form of the command was:
curl -s -X POST ${ip1} -H "content-type: application/json" \
-d '{"args":["org1","scatest'$j$i'","27-06-2018"]}'

How to set command line argument using a variable in bash

I set a command line argument as below:
$TOKENARG='Authorization: Bearer 9042f9a3caacc63419be489aefec02a5eae338c33'
curl -v -X DELETE -H $(echo $TOKENARG) http://localhost:3001/api/v1/articles/3
And desired result is:
curl -v -X DELETE -H 'Authorization: Bearer 9042f9a3caacc63419be489aefec02a5eae338c33' http://localhost:3001/api/v1/articles/3
But when I run the above one it doesn't work as expected and returns the following messages:
curl: (6) Could not resolve host: Bearer
* Rebuilt URL to: 9042f9a3caacc63419be489aefec02a5eae338c33
Could not resolve host: 9042f9a3caacc63419be489aefec02a5eae338c33
How should I pass argument using a variable?
Because you don't quote your command substitution, the string is split up into three words, Authorization:, Bearer and 9042f9a3caacc63419be489aefec02a5eae338c33. To prevent that, you could quote it:
curl -v -X DELETE -H "$(echo $TOKENARG)" http://localhost:3001/api/v1/articles/3
But you don't need echo and the command substitution at all: $(command) has the same output as command, so you can use
curl -v -X DELETE -H "$TOKENARG" http://localhost:3001/api/v1/articles/3
Side note: all uppercase variable names should be used for environment variables only, see for example the POSIX spec (fourth paragraph), so better would be
$tokenarg='Authorization: Bearer 9042f9a3caacc63419be489aefec02a5eae338c33'
curl -v -X DELETE -H "$tokenarg" http://localhost:3001/api/v1/articles/3

Why is this bash/CURL call to REST services giving inconsistent results with parameters?

I have written a smoke-testing script that uses BASH script & Curl to test RESTful web services we're working on. The script reads a file, and interprets each line as a URL suffix and parameters for a Curl REST call.
Unfortunately, the script gives unexpected results when I adapted it to run HTTP POST calls as well as GET calls. It does not give the same results running the command on its own, vs. in script:
The BASH Script:
IFS=$'\n' #Don't split an input URL line at spaces
RESTHOST='hostNameAndPath' #Can't give this out
URL="/activation/v2/activationInfo --header 'Content-Type:Application/xml'"
URL2="/activation/v2/activationInfo"
OUTPUT=`curl -sL -m 30 -w "%{http_code}" -o /dev/null $RESTHOST$URL -d #"./activation_post.txt" -X POST`
echo 'out:' $OUTPUT
OUTPUT2=`curl -sL -m 30 -w "%{http_code}" -o /dev/null $RESTHOST$URL2 --header 'Content-Type:Application/xml' -d #'./activation_post.txt' -X POST`
echo 'out2:' $OUTPUT2
Results Out:
out: 505
out2: 200
So, the first call fails (HTTP return code 505, HTTP Version Not Supported), and the second call succeeds (return code "OK").
Why does the first call fail, and how do I fix it? I've verified they should execute the same command (evaluating in echo). I am sure there is something basic I'm missing, as I am just NOW learning Bash scripting.
I think I have found the problem! It is caused by IFS=$'\n'! Because of this, variable expansion does not work as expected. It does not let to split the arguments specified in the URL string!
As a result the SERVER_PROTOCOL variable on the server side will be set to '--header Content-Type:Application/xml HTTP/1.1' instead of "HTTP/1.1", and the CONTENT_TYPE will be 'application/x-www-form-urlencoded' instead of 'Application/xml'.
To show the root of the problem in detail:
VAR="Solaris East"
printf "+%s+ " $VAR
echo "==="
IFS=$'\n'
printf "+%s+ " $VAR
Output:
+Solaris+ +East+ ===
+Solaris East+
So the $VAR expansion does not work as expected because of IFS=$'\n'!
Solution: Do not use IFS=$'\n' and replace space to %20 in URL!
URL=${URL2// /%20}" --header Content-Type:Application/xml"
In this case your first curl call will work properly!
If You still use IFS=$'\n' and give --header option in the command line it will not work properly if URL contains a space, because the server will fail to process it (I tested on apache)!
Even You still cannot use HEADER="--header Content-Type:Application/xml" as expanding $HEADER will result one(!) argument for curl, namely --header Content-Type:Application/xml instead of splitting them into two.
So I may suggest to replace spaces in URL to %20 anyway!
The single quotes surrounding Content-Type:Application/xml, because they are quoted in the value of URL are treated as literal quotes and not removed when $URL is expanded in that call to curl. As a result, you are passing an invalid HTTP header. Just use
URL="/activation/v2/activationInfo --header Content-Type:Application/xml"
OUTPUT=`curl -sL -m 30 -w "%{http_code}" -o /dev/null $RESTHOST$URL -d #"./activation_post.txt" -X POST`
However, it's not a great idea to rely on word-splitting like this to combine two separate pieces of the call to curl in a single variable. Try something like this instead:
URLPATH="activation/v2/activationInfo"
HEADERS=("--header" "Content-Type:Application/xml")
OUTPUT=$( curl -SL -m 30 -w "%{http_code}" -o /dev/null "$RESTHOST/$URL" "${HEADERS[#]}" -d #'./activation_post.txt' -X POST )

Resources