Get response body and show HTTP code by curl

99,767

Solution 1

It looks like the content of the response is a single line. You could use two read calls to read two lines:

curl -s -w "\n%{http_code}" 'https://swapi.co/api/people/1/?format=json' | {
    read body
    read code
    echo $code
    jq .name <<< "$body"
}

Solution 2

Solution with return body and HTTP code at last line:

response=$(curl -s -w "\n%{http_code}" https://swapi.co/api/people/1/?format=json)
response=(${response[@]}) # convert to array
code=${response[-1]} # get last element (last line)
body=${response[@]::${#response[@]}-1} # get all elements except last
name=$(echo $body | jq '.name')
echo $code
echo "name: "$name

But still I would rather do this with two separate variables/streams instead of concatenate response body and HTTP code in one variable.

Solution 3

Tested on bash4 on Ubuntu 18.04LTS:

IFS=$'\n' read -d "" body code  < <(curl -s -w "\n%{http_code}\n" "${uri}")

This forces the output of curl to be on two lines. The change to IFS makes the linefeed the only field separator and the -d "" forces read to read beyond the line feed, treating the two lines as though they are one. Not the most elegant solution, but a one-liner.

Share:
99,767

Related videos on Youtube

mkczyk
Author by

mkczyk

I'm student of IT in Poland. Sorry for my bad English. I'm learning. If you see my mistake, you can correct me, please.

Updated on September 18, 2022

Comments

  • mkczyk
    mkczyk over 1 year

    I have endpoint which returns JSON (response body). I need get by curl the response body and process it (for example using jq). It works:

    response=$(curl -s https://swapi.co/api/people/1/?format=json)
    name=$(echo $response tmpFile | jq '.name') # irrelevant command, but I need here response body
    echo "name:"$name
    

    But I also need show the HTTP Code (to show if the request is succeed):

    curl -s -w "%{http_code}\n" -o /dev/null https://swapi.co/api/people/1/?format=json
    

    How get the response body to variable and show HTTP code at the same time (one request)?


    I find out solution witch temporary file:

    touch tmpFile
    curl -s -w "%{http_code}\n" -o tmpFile https://swapi.co/api/people/1/?format=json
    name=$(cat tmpFile | jq '.name') # irrelevant command, but I need here only body response
    echo "name: "$name
    rm tmpFile
    

    How to do without creating file?

    I try with named pipe (but it still need to creating file on disk...):

    mkfifo tmpFifo
    curl -s -w "%{http_code}\n" -o tmpFifo https://swapi.co/api/people/1/?format=json
    name=$(cat tmpFifo | jq '.name') # irrelevant command, but I need here only body response
    echo "name: "$name
    rm tmpFifo
    

    But the named pipe is not removing.

    There is solution without creating any file, for example only witch variables or streams?

  • Dave Babbitt
    Dave Babbitt almost 4 years
    I would add IFS=$'\n' to the first line to ensure that the value in the code variable doesn't truncate on its last space character.
  • Pmpr
    Pmpr about 3 years
    I can not get it to work. could you please add some explanations?
  • Admin
    Admin almost 2 years
    I had to add the IFS=$'\n' to the array conversion line, not literally the first line. Also before Bash 4.2 (I think) I had to use code=${response[*]: -1} to get the last element