cURL requests in bash

I am trying to write a script which will execute two curl requests in bash. This is my code:

#!/bin/bash

ipadd="192.168.1.1"
start_url="http://$ipadd/startPlayer"
stop_url="http://$ipadd/stopPlayer"
header1="Accept: application/json"
header2="Content-Type: application/json"
stp="28508ab5-9591-47ed-9445-d5e8e9bafff6"

function start_player {
        curl --verbose -H "${header1}" -H "${header2}" -X PUT -d '{"id": "$stp"}' ${start_url}
}

function stop_player {
        curl -X PUT $stop_url
}

stop_player
start_player

The stop_player function works without a problem, but the first function doesn’t work. I just want to execute the following CURL request: curl --verbose -H "Accept: application/json" -H "Content-Type: application/json" -X PUT -d '{"id": "c67664db-bef7-4f3e-903f-0be43cb1e8f6"}' http://192.168.1.1/startPlayer If I echo the start_player function, the output is exactly as it should be, but if I execute the start_player function I got an error: Could not resolve host: application. I think it is because bash is splitting the headers but why it works fine with echo, but not in bash?

Answer

You wrote:

curl --verbose -H "${header1}" -H "${header2}" ...

but it looks like you really want:

curl --verbose -H "${header1}" -H "${header2}" ...

With the values you have set for header1 and header2, the former would cause curl to receive as parameters --verbose, -H, "Accept:, application/json", -H, "Content-Type:, and application/json", whereas you really want each header value as its own token, which the unescaped double quotes will provide.

Additionally, I see you pass -d '{"id": "$stp"}'. You probably want -d "{"id": "$stp"}" there.


As to your question about why whings appear to work fine within echo, “but not in bash”, well, things did not actually work OK with echo, it’s just that it makes that fact hard to see.

Compare:

$ h1='Accept: foo'; h2='Content-Type: bar'

## Looks good, is actually wrong:
$ echo curl -H "$h1" -H "$h2"
curl -H "Accept: foo" -H "Content-Type: bar"

## If we ask printf to print one parameter per line:
$ printf '%sn' curl -H "$h1" -H "$h2"
curl
-H
"Accept:
foo"
-H
"Content-Type:
bar"

With:

## Looks different from the bash command, is actually right:
$ echo curl -H "$h1" -H "$h2"
curl -H Accept: foo -H Content-Type: bar

## This is more obvious if we ask printf to print one parameter per line:
$ printf '%sn' curl -H "$h1" -H "$h2"
curl
-H
Accept: foo
-H
Content-Type: bar

Leave a Reply

Your email address will not be published. Required fields are marked *