cURL requests in bash

9,498

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 '%s\n' 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 '%s\n' curl -H "$h1" -H "$h2"
curl
-H
Accept: foo
-H
Content-Type: bar
Share:
9,498
Georgi Stoyanov
Author by

Georgi Stoyanov

Updated on September 18, 2022

Comments

  • Georgi Stoyanov
    Georgi Stoyanov over 1 year

    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?

  • Georgi Stoyanov
    Georgi Stoyanov about 6 years
    This won't work it will transmit the following: curl --verbose -H Accept: application/json -H Content-Type: application/json without the quotations around.
  • dhag
    dhag about 6 years
    I suggest you actually give it a try.
  • Georgi Stoyanov
    Georgi Stoyanov about 6 years
    I did, it doesn't work. I got error 500 Internal Error.
  • dhag
    dhag about 6 years
    Thanks for mentioning the new error message! This could be due to the broken JSON you were passing.
  • Georgi Stoyanov
    Georgi Stoyanov about 6 years
    actually the problem was in the JSON request and I needed to exchange the single with double quotes, now it works, Thanks a lot @dhag!!!