Search code examples
shellcurlhttp-headersaccess-token

How to run a curl command with headers using shell script


I tried to run a shell script which contains a curl command with its required headers as below.

counter=1
H1='Content-Type: application/json'
H2='Accept: application/json'
H3='Authorization: Bearer a0a9bb26-bb7d-3645-9679-2cd72e2b4c57'
URL='http://localhost:8280/mbrnd_new/v1/post'

while [ $counter -le 10 ]

do

TEST="curl -X POST --header $H1 --header $H2 --header $H3 -d @s_100mb.xml $URL"
echo $TEST
RESPONSE=`$TEST`
echo $RESPONSE
sleep 5
done
echo "All done"

It gives an error as

curl: (6) Could not resolve host: application
curl: (6) Could not resolve host: Bearer
curl: (6) Could not resolve host: a0a9bb26-bb7d-3645-9679-2cd72e2b4c57
<ams:fault xmlns:ams="http://wso2.org/apimanager/security"><ams:code>900902</ams:code><ams:message>Missing Credentials</ams:message><ams:description>Required OAuth credentials not provided. Make sure your API invocation call has a header: "Authorization: Bearer ACCESS_TOKEN"</ams:description></ams:fault>

The given access token and other header parameters are correct. It works fine when the 'curl' is called directly.

I tried different methods like using \" but nothing worked. I would be grateful if someone can provide a proper answer to this.

Thanks.


Solution

  • The command you want to execute is something like:

    curl -X POST --header "$H1" --header "$H2" --header "$H3" -d @s_100mb.xml "$URL"
    

    (I'll use -H instead of --header as it's shorter.)

    The easiest way to do it is

    response=$(curl -X POST -H "$H1" -H "$H2" -H "$H3" -d @s_100mb.xml "$URL")
    

    The problem with your solution is that you're not delimiting the header values at all:

    curl -X POST -H $H1
    

    If the content of H1 is foo: bar, then this will expand to

    curl -X POST -H foo bar
    

    and that will be interpreted as

    curl -X POST -H (foo:) bar
    

    (using ( and ) only to illustrate precedence, nothing like this works in shell), i.e. bar will be taken to be the first positional argument, which happens to be the hostname, leading to strange errors you see.

    What you want is

    curl -X POST -H (foo: bar)
    

    which can be achieved by properly wrapping the expansions in quotes as illustrated above.

    Also, you should prefer $(cmd) to `cmd`.

    As a final piece of advice, if you're learning how to use the shell, it may be wise avoiding multiple expansions, i.e. don't store your command in a CMD variable to $($CMD) it later, as that leads to multiple expansions in multiple places (first where CMD was assigned, second when CMD was expanded in the $(...) sub-shell), making it hard to understand what the heck is going on.