Vuoi arricciare per generare il codice di stato HTTP?


799

Sto usando curldalla riga di comando su Linux per inviare richieste HTTP. I corpi di risposta sono stampati sullo standard, il che va bene, ma dalla pagina man non riesco a vedere come ottenere l'arricciatura per stampare il codice di stato HTTP dalla risposta (404, 403 ecc.). È possibile?


Per quanto mi riguarda, posso vedere dal manuale come ottenere il codice di stato HTTP, ma l'opzione -w non funziona. Ho segnalato il bug ad Apple.
Nicolas Barbulesco,

19
La -ibandiera, come in curl -i https://www.example.com/, è probabilmente quello che vuoi, come da superuser.com/a/514798/190188
caw

Perché non solo qualcosa del genere curl -IL http://www.example.com | grep "^HTTP\/"?
St3an,

Non al sé futuro: la risposta che desideri è probabilmente quella di Cyril David (attualmente in 4a posizione)
WhiteHotLoveTiger

Risposte:


525

Questo dovrebbe funzionare per te se il web server è in grado di rispondere alle richieste HEAD (questo non eseguirà a GET):

curl -I http://www.example.org

Inoltre, per consentire a cURL di seguire i reindirizzamenti (stati 3xx) aggiungere -L.


155
NB: curl -Ifa una richiesta HTTP HEAD, che può essere problematica per testare il codice di stato HTTP per alcuni server e servizi di applicazioni web
Jay Taylor

16
E per ottenere solo il numero di stato, reindirizzalo ahead -n 1|cut -d$' ' -f2
Benubird,

33
Non dimenticate di reindirizzare stderr del riccio: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Aggiungi -L per arricciare se hai bisogno dello stato finale dopo i reindirizzamenti.
Aaron Blenkush,

1
Seguire il reindirizzamento dopo aver eseguito solo una richiesta HEAD può causare comportamenti interessanti, a seconda della modalità di programmazione dell'app.
Scott McIntyre,

31
curl -I -X GETinvierà una richiesta GET, ma fornirà lo stesso output.
jiggy,

835

Un modo più specifico per stampare solo il codice di stato HTTP è qualcosa sulla falsariga di:

curl -s -o /dev/null -w "%{http_code}" http://www.example.org/

Molto più facile lavorare con gli script, in quanto non richiede alcun analisi :-)

È -Ipossibile aggiungere il parametro per migliorare le prestazioni del carico di risposta. Questo parametro richiede solo lo stato / le intestazioni della risposta, senza il corpo della risposta di download.

Nota: %{http_code} ritorna sulla prima riga del payload HTTP

vale a dire:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/

54
-w "% {http_code}" è il bit che stampa il codice di stato. Puoi aggiungere una o due righe per separare il codice dal corpo (-w "\ n \ n% {http_code} \ n")
Jeffrey Martinez,

7
Caspita, questa /dev/nullcosa funziona anche nella versione Windows di arricciatura che sto usando.
Uwe Keim,

3
Credo che questo scarica l'intero file anche se tutto va in / dev / null, quindi non è l'ideale per controllare il codice di stato per file di grandi dimensioni. httping -c 1 -s -G -memette un GET e non scarica l'intero file, anche se mi rendo conto che questa domanda riguarda specificamente l'arricciatura.
Roman,

40
FYI: -s= Non mostrare l'avanzamento del download, -o /dev/null= non visualizzare il corpo, -w "%{http_code}"= Scrivi il codice di risposta http su stdout dopo l'uscita.
Ajedi32

1
Sono richieste le virgolette intorno a "% {http_code}"?
Hakan Baba,

217

Se vuoi vedere l'intestazione e il risultato puoi usare l'opzione dettagliata:

curl -v http://www.example.org
curl --verbose http://www.example.org

Lo stato verrà visualizzato nell'intestazione. Per esempio

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity

26
+1 per indicare la bandiera dettagliata fornisce i dettagli extra. Ottimo per testare le app REST.
MrOodles,

8
+1 molto facile da usare quando si effettua una richiesta POST (curl -v --data "...")
MegaTux

1
Li divide anche in due diversi output di file (dettagli dello stato http su stderr e corpo di risposta su stdout)
phil294

201

È possibile stampare il codice di stato, oltre a tutte le intestazioni, nel modo seguente:

curl -i http://example.org

La cosa positiva -iè che funziona anche con -X POST.


36
Molto meglio della risposta accettata (che fa una richiesta HEAD).
neu242,

10
Forse ovvio, ma -ifunziona con qualsiasi metodo HTTP, non solo GETe POST... :)
mac

3
la risposta migliore in quanto produce arricciatura sia delle intestazioni che del corpo, rendendola adatta per la maggior parte dei compiti quando usata in uno script
Sarge Borsch

6
Questa è la risposta migliore e può essere utilizzata insieme a -s(non mostrare i parametri di errore o i messaggi di errore) e -S(dopo tutto mostra i messaggi di errore)
Jonathan Hartley,

69

Se si desidera acquisire il codice di stato HTTP in una variabile, ma reindirizzare comunque il contenuto su STDOUT, è necessario creare due STDOUT. Puoi farlo con la sostituzione di processo> () e la sostituzione di comando $ () .

Innanzitutto, crea un descrittore di file 3per il processo corrente 'STDOUT con exec 3>&1.

Quindi, utilizzare l' -oopzione curl per reindirizzare il contenuto della risposta a un FIFO temporaneo utilizzando la sostituzione dei comandi, quindi all'interno di tale sostituzione dei comandi, reindirizzare l'output al descrittore di file STDOUT del processo corrente 3con -o >(cat >&3).

Mettendo tutto insieme in bash 3.2.57(1)-release(standard per macOS):

# creates a new file descriptor 3 that redirects to 1 (STDOUT)
exec 3>&1 
# Run curl in a separate command, capturing output of -w "%{http_code}" into HTTP_STATUS
# and sending the content to this command's STDOUT with -o >(cat >&3)
HTTP_STATUS=$(curl -w "%{http_code}" -o >(cat >&3) 'http://example.com')

Nota che questo non funziona /bin/shcome notato da SamK nei commenti qui sotto .


5
È una vera chiazza di petrolio ... e mi piace!
spyle

3
Ora come posso reindirizzare l'output a un'altra variabile?
Roger Filmyer,

1
L'output è attivo STDOUT, quindi dovresti essere in grado di reindirizzare l'output dal comando verso qualsiasi punto ti piaccia proprio come un normale comando. Non l'ho ancora provato.
Heath Borders

1
Non funziona con / bin / sh.
SamK,

buona risposta, puoi anche reindirizzare a un file reale e cat in un secondo momento se vuoi la portabilità delle shell
akostadinov

32

Ridefinisci output arricciatura:

curl -sw '%{http_code}' http://example.org

Può essere utilizzato con qualsiasi tipo di richiesta.


-k (--insecure) è prioritario -s (silenzioso).
Ravichandra,

16

SOLO codice di stato

[0]$ curl -LI http://www.example.org -o /dev/null -w '%{http_code}\n' -s
[0]$ 200

Tutto il merito di questo GIST


11

Questa è una curl --faillimitazione dolorosa . Da man curl:

-f, --fail (HTTP) non riesce in modo silenzioso (nessun output) su errori del server

Ma non v'è alcun modo per ottenere sia il codice di ritorno diverso da zero e il corpo della risposta in stdout.

Sulla base della risposta di pvandenberk e di questo altro trucco molto utile appreso su SO , ecco una soluzione alternativa:

curl_with_error_code () {
    _curl_with_error_code "$@" | sed '$d'
}
_curl_with_error_code () {
    local curl_error_code http_code
    exec 17>&1
    http_code=$(curl --write-out '\n%{http_code}\n' "$@" | tee /dev/fd/17 | tail -n 1)
    curl_error_code=$?
    exec 17>&-
    if [ $curl_error_code -ne 0 ]; then
        return $curl_error_code
    fi
    if [ $http_code -ge 400 ] && [ $http_code -lt 600 ]; then
        echo "HTTP $http_code" >&2
        return 127
    fi
}

Questa funzione si comporta esattamente come curl, ma restituirà 127 (un codice di ritorno non utilizzato da curl) nel caso di un codice HTTP nell'intervallo [400, 600 [.


D'accordo, non riuscire a vedere l'output dell'errore è una dolorosa limitazione del --fail altrimenti molto utile. Come è possibile diagnosticare un errore API REST senza visualizzare l'output dell'errore? È così sfortunato che il curder manutentore del ricciolo insiste ostinatamente a non fornire un errore --fail-but-show-. github.com/curl/curl/issues/1978
jamshid

Come indicato nella documentazione, non funziona per il codice HTTP 401 e 407 :(
Logan Mzz

11

Questo invierà una richiesta di url, otterrà solo la prima riga della risposta, la dividerà su blocchi e selezionerà la seconda.

Contiene il codice di risposta

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2

1
Puoi spiegare cosa fa questo codice e come risolve il problema dato dall'OP? Il codice inspiegabile può apparire non attendibile e pericoloso per gli utenti.
bwDraco,

1
Certo, inviamo una richiesta per url, otteniamo solo la prima riga della risposta, la dividiamo in blocchi e selezioniamo la seconda. Contiene il codice di risposta che OP sta cercando.
Filip Spiridonov,

9

Per una richiesta POST, ha funzionato:

curl -w 'RESP_CODE:%{response_code}' -s -X POST --data '{"asda":"asd"}' http://example.com --header "Content-Type:application/json"|grep -o  'RESP_CODE:[1-4][0-9][0-9]'

6

Utilizzare il seguente comando cURL e pipe per grep in questo modo:

$ curl -I -s -L http://example.com/v3/get_list | grep "HTTP / 1.1"

Ecco cosa fa ogni bandiera:

  • -I: Mostra solo le intestazioni di risposta
  • -s: Silenzioso: non mostra la barra di avanzamento
  • -L: Segui le Location:intestazioni

Ecco un link ai codici di stato HTTP .

Esegui dalla riga di comando. Questo ricciolo viene eseguito in modalità silenziosa, segue tutti i reindirizzamenti, ottiene le intestazioni HTTP. grep stamperà il codice di stato HTTP sull'output standard.


5
curl -so -i /dev/null -w "%{http_code}"  http://www.any_example.com

Ciò restituirà le seguenti informazioni:

  1. dati di risposta, se qualsiasi dato viene restituito dall'API come errore
  2. codice di stato

Questo non segue i reindirizzamenti. Questa risposta esistente è migliore superuser.com/a/442395/475508
cricket_007

Certo, puoi riferirti anche a quello !!
srana,

4

Ecco qualche comando di arricciatura che sta utilizzando GETe che restituisce il codice HTTP.

curl -so /dev/null -w '%{response_code}' http://www.example.org

Ricorda che sta usando l'approccio seguente HEAD, che è più veloce ma potrebbe non funzionare bene con alcuni server HTTP meno conformi al Web.

 curl -I http://www.example.org

Almeno non funziona su OS X.
Ain,

Funziona bene per me su OS X High Sierra 10.13.6.
Ben Baron,

4

Un esempio di come utilizzare i codici di risposta. Lo uso per scaricare nuovamente i database Geolite solo se sono stati modificati ( -z) e anche per i seguenti reindirizzamenti ( -L):

url=http://example.com/file.gz
file=$(basename $url)

response=$(curl -L -s -o $file -z $file $url -w "%{http_code}")

case "$response" in
        200) do_something ;;
        301) do_something ;;
        304) printf "Received: HTTP $response (file unchanged) ==> $url\n" ;;
        404) printf "Received: HTTP $response (file not found) ==> $url\n" ;;
          *) printf "Received: HTTP $response ==> $url\n" ;;
esac

3

L'OP vuole conoscere il codice di stato. Spesso quando scarichi un file vuoi anche avere un'idea delle sue dimensioni, quindi uso prima l'arricciatura per mostrare il codice di stato e le dimensioni del file, quindi spengo il file dettagliato e diretto nel luogo e nel nome che desidero:

curl -R -s -S -w  "\nhttp: %{http_code} %{size_download}\n" -o /Users/myfiles/the_local_name.html http://archive.onweb.com/the_online_name.html

Quindi aspetto la finitura del ricciolo

wait ${!}

prima di eseguire il comando successivo. Quanto sopra usato in uno script con molti comandi come sopra fornisce una buona risposta come:

http: 200 42824

http: 200 34728

http: 200 35452

Si noti che -o in curl deve essere seguito dal percorso completo del file + nome del file. Ciò consente quindi di salvare i file in una struttura di nomi sensata quando li d / l con arricciatura. Si noti inoltre che -s e -S usati insieme disattivano l'output ma mostrano errori. Si noti inoltre che -R tenta di impostare il timestamp del file su quello del file web.

La mia risposta si basa su ciò che inizialmente suggeriva @pvandenberk, ma in realtà salva il file da qualche parte, invece di limitarsi a dirigere a / dev / null.


1

Dividi il contenuto di output in stdoute il codice di stato HTTP in stderr:

curl http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

Se si desidera solo il codice di stato HTTP per stderr, è --silentpossibile utilizzare:

curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

Lo stream desiderato può quindi essere scelto reindirizzando uno indesiderato a /dev/null:

$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 1>/dev/null
200
$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 2>/dev/null
<!doctype html>
...

Si noti che affinché il secondo reindirizzamento si comporti come desiderato, è necessario eseguire il comando curl in subshell.


1
Richiede la bashsostituzione del processo.
Jaakko

@Bruno, ho cambiato l'esempio da superuser.com/revisions/1444693/2 , poiché penso che i /tmp/out /tmp/errfile possano causare risultati imprevisti se eseguiti in parallelo.
Jaakko
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.