Curl per restituire il codice di stato http insieme alla risposta


113

Uso curl per ottenere intestazioni http per trovare il codice di stato http e anche per restituire la risposta. Ottengo le intestazioni http con il comando

curl -I http://localhost

Per ottenere la risposta, utilizzo il comando

curl http://localhost

Non appena uso il flag -I, ottengo solo le intestazioni e la risposta non è più lì. C'è un modo per ottenere sia la risposta http che le intestazioni / codice di stato http in un unico comando?


Risposte:


113

Sono stato in grado di ottenere una soluzione guardando il documento curl che specifica di utilizzare -per l'output per ottenere l'output su stdout.

curl -o - http://localhost

Per ottenere la risposta con solo il codice di ritorno http, potrei semplicemente fare

curl -o /dev/null -s -w "%{http_code}\n" http://localhost

14
o useresti -i. O forse -vse ti piacciono anche alcune informazioni aggiuntive.
Daniel Stenberg,

2
Grazie @DanielStenberg. La risposta accettata non ha funzionato per me, semplicemente usando -i ha funzionato.
Alejandro Cotilla

manca il tuo secondo comando -I @randominstanceOfLivingThing, a meno che non sia intenzionalmente un'opzione vuota? Non funziona per me senza però
mdo123

2
-o -Ifinisce per creare un file chiamato letteralmente " -I" nel CWD. Qualcun altro lo vede? La soluzione è-o/dev/null -I
JDS

Rimosso il -I. L'ho notato e corretto ora. Non hai bisogno del -I.
randominstanceOfLivingThing


36

Uso questo comando per stampare il codice di stato senza nessun altro output. Inoltre, eseguirà solo una richiesta HEAD e seguirà il reindirizzamento (rispettivamente -Ie -L).

curl -o -I -L -s -w "%{http_code}" http://localhost

Ciò semplifica molto il controllo del codice di stato in uno script di integrità:

sh -c '[ $(curl -o -I -L -s -w "%{http_code}" http://localhost) -eq 200 ]'

5
Questo è già stato risposto un anno fa. Quale nuovo valore porta la tua risposta? Per favore scrivi anche qualche spiegazione alla tua risposta.
Maciej Jureczko

11
@MaciejJureczko - Il valore è semplice. Ai fini dello scripting, questa risposta è la migliore di tutte le altre risposte, perché fornisce un unico codice di stato invece di molte righe di spazzatura insieme a detto codice di stato.
aggregate1166877

2
Ma l'OP afferma specificamente che vogliono sia il codice di stato che il corpo della risposta. Sanno come ottenere solo il codice di risposta (indicato nella domanda)
wottle

2
Ogni volta che lo uso curl -o -I -L -s -w "%{http_code}" http://localhostviene creato un file chiamato -I, per aggirare questo ho aggiunto un posto per l'output del file implicito da -oandare, vale a dire /dev/null:curl -o /dev/null -I -L -s -w "%{http_code}" http://localhost
Questo è il

Tuttavia, HEAD non produrrà sempre lo stesso output di una richiesta, dipende dal modo in cui risponde il server. Quindi questa non è davvero una risposta.
Eddie

28

Ho trovato questa domanda perché volevo SIA la risposta che il contenuto per aggiungere una gestione degli errori per l'utente.

È possibile stampare il codice di stato HTTP su std out e scrivere il contenuto in un altro file.

curl -s -o response.txt -w "%{http_code}" http://example.com

Questo ti consente di utilizzare la logica per decidere se vale la pena elaborare la risposta.

http_response=$(curl -s -o response.txt -w "%{http_code}" http://example.com)
if [ $http_response != "200" ]; then
    # handle error
else
    echo "Server returned:"
    cat response.txt    
fi

cos'è http_code? Non lo capisco, necessita di ulteriori spiegazioni per favore
Alexander Mills

chiarito sopra, si riferisce al codice di stato HTTP - developer.mozilla.org/en-US/docs/Web/HTTP/Status
Eddie

22

L' -iopzione è quella che desideri:

curl -i http://localhost

-i, --include Include le intestazioni di protocollo nell'output (H / F)

In alternativa puoi usare l'opzione dettagliata:

curl -v http://localhost

-v, --verbose Rendi l'operazione più loquace


16

Ho usato questo:

    request_cmd="$(curl -i -o - --silent -X GET --header 'Accept: application/json' --header 'Authorization: _your_auth_code==' 'https://example.com')"

Per ottenere lo stato HTTP

    http_status=$(echo "$request_cmd" | grep HTTP |  awk '{print $2}')
    echo $http_status

Per ottenere il corpo della risposta ho usato questo

    output_response=$(echo "$request_cmd" | grep body)
    echo $output_response

8

Questo comando

 curl http://localhost -w ", %{http_code}"

otterrà il corpo e lo stato separati da virgole; puoi dividerli per tirarli fuori.

Puoi cambiare il delimitatore come preferisci.


2
buon suggerimento! è possibile aggiungere il codice di stato davanti all'uscita?
Psychozoic

6

Per l'utilizzo programmatico, utilizzo quanto segue:

curlwithcode() {
    code=0
    # Run curl in a separate command, capturing output of -w "%{http_code}" into statuscode
    # and sending the content to a file with -o >(cat >/tmp/curl_body)
    statuscode=$(curl -w "%{http_code}" \
        -o >(cat >/tmp/curl_body) \
        "$@"
    ) || code="$?"

    body="$(cat /tmp/curl_body)"
    echo "statuscode : $statuscode"
    echo "exitcode : $code"
    echo "body : $body"
}

curlwithcode https://api.github.com/users/tj

Mostra il seguente output:

statuscode : 200
exitcode : 0
body : {
  "login": "tj",
  "id": 25254,
  ...
}

5

Questo è un modo per recuperare il corpo "AND" del codice di stato e formattarlo in un json appropriato o in qualsiasi altro formato funzioni per te. Alcuni potrebbero obiettare che è l'uso errato dell'opzione di formato di scrittura, ma questo funziona per me quando ho bisogno sia del corpo che del codice di stato nei miei script per controllare il codice di stato e ritrasmettere le risposte dal server.

curl -X GET -w "%{stderr}{\"status\": \"%{http_code}\", \"body\":\"%{stdout}\"}"  -s -o - https://github.com 2>&1

esegui il codice sopra e dovresti recuperare un json in questo formato:

{
"status" : <status code>,
"body" : <body of response>
}

con l'opzione -w write format, poiché viene stampato per primo stderr, puoi formattare l'output con var http_code e inserire il corpo della risposta in un valore (corpo) e seguire l'inclusione usando var stdout. Quindi reindirizza il tuo output stderr a stdout e sarai in grado di combinare sia http_code che il corpo della risposta in un output pulito


1
Ho ricevuto il seguente errore - curl: unknown --write-out variable: 'stderr'ecurl: unknown --write-out variable: 'stdout'
ALex_hha

La pagina man curl.haxx.se/docs/manpage.html mostra la variabile disponibile. Non sono sicuro del motivo per cui stderr non viene riconosciuto dal tuo curl, il curl im su un macbook. Da questo documento curl di Linux, computerhope.com/unix/curl.htm , non vedo nemmeno stderr come una variabile. Forse questa è una variazione del sistema operativo.
Huy Tran,

L'unico problema che ho con questo è se il tuo corpo ha virgolette, ad esempio se è json, il corpo renderà la risposta json sopra json non valida
annunciatore

abbastanza giusto @thannuncer, mi aspetto che lo sviluppatore si adegui di conseguenza poiché non tutte le risposte saranno json standard. Ci sono stati alcuni casi in cui ho dovuto adeguarmi a causa della natura della risposta.
Huy Tran

2

Il mio modo per ottenere questo risultato :

Per ottenere entrambi (intestazione e corpo), di solito eseguo un curl -D- <url>come in:

$ curl -D- http://localhost:1234/foo
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 20:59:21 GMT

{"data":["out.csv"]}

Questo scaricherà le intestazioni ( -D) su stdout ( -) (Cerca --dump-headerin man curl ).

IMHO anche molto utile in questo contesto:

Uso spesso jq per ottenere la formattazione dei dati json (ad esempio da alcune API rest). Ma poiché jq non si aspetta un'intestazione HTTP, il trucco è stampare le intestazioni su stderr usando -D/dev/stderr. Nota che questa volta usiamo anche -sS(--silent, --show-errors) per sopprimere l'indicatore di avanzamento (perché scriviamo su una pipe).

$ curl -sSD/dev/stderr http://localhost:1231/foo | jq .
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:08:22 GMT

{
  "data": [
    "out.csv"
  ]
}

Immagino che questo possa essere utile anche se desideri stampare le intestazioni (per un'ispezione rapida) sulla console ma reindirizzare il corpo a un file (ad esempio, quando è una specie di binario per non rovinare il tuo terminale):

$ curl -sSD/dev/stderr http://localhost:1231 > /dev/null
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:20:02 GMT

Attenzione: NON è la stessa cosa di curl -I <url>! Come -Ieseguirà una HEADrichiesta e non una GETrichiesta (cerca --headin man curl . Sì: per la maggior parte dei server HTTP questo produrrà lo stesso risultato. Ma conosco molte applicazioni aziendali che non implementano affatto la HEADrichiesta ;-P


-2
while : ; do curl -sL -w "%{http_code} %{url_effective}\\n" http://host -o /dev/null; done

1
Perché dovresti metterlo in un ciclo while? Si prega di espandere e spiegare la risposta.
Uberhumus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.