2011-04-18 10:28:57 +0000 2011-04-18 10:28:57 +0000
864
864

Ottenere curl per l'uscita del codice di stato HTTP?

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

Risposte (16)

906
906
906
2012-06-28 00:25:11 +0000

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

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

Molto più facile da lavorare negli script, in quanto non richiede alcun parsing :-)

Il parametro -I potrebbe essere aggiunto per migliorare le prestazioni del carico di risposta. Questo parametro richiede solo la richiesta di stato/intestazioni di risposta, senza scaricare il corpo della risposta.

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

cioè:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/
572
572
572
2011-04-18 10:56:02 +0000

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

curl -I http://www.example.org
``` &001 


Come aggiunta, per permettere a cURL di seguire i reindirizzamenti (3xx stati) aggiungere -L.
237
237
237
2012-05-03 04:28:44 +0000

Se si vuole vedere l'intestazione e il risultato si può usare l'opzione verbosa:

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

Lo stato apparirà nell'intestazione. Es.

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity
218
218
218
2012-12-04 20:45:49 +0000

È possibile stampare il codice di stato, oltre a tutte le intestazioni, facendo quanto segue:

curl -i http://example.org

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

71
71
71
2015-01-08 20:59:43 +0000

Se si vuole catturare il codice di stato HTTP in una variabile, ma si vuole comunque reindirizzare il contenuto verso STDOUT, è necessario creare due STDOUT. Lo si può fare con sostituzione del processo >>() e sostituzione del comando $() .

Innanzitutto, creare un file descriptor 3 per il proprio processo corrente’ STDOUT con exec 3>&1.

Poi, usare l'opzione -o di curl per reindirizzare il contenuto della risposta ad un fifo temporaneo usando la sostituzione di comando, e poi, all'interno di tale sostituzione di comando, reindirizzare l'output di nuovo al vostro attuale processo STDOUT file descriptor 3 con -o >(cat >&3).

Mettere 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')

Si noti che questo non funziona in /bin/sh come SamK ha notato nei commenti qui sotto .

35
35
35
2014-08-05 18:18:29 +0000

Ridefinire l'uscita dell'arricciatura:

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

Può essere utilizzato con qualsiasi tipo di richiesta.

19
19
19
2017-02-08 10:44:15 +0000

Codice di stato ONLY

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

Tutti i crediti a questo GIST

14
14
14
2016-04-06 13:08:49 +0000

Questa è una dolorosa limitazione curl --fail. Da man curl :

-f, –fail (HTTP) Fail silenziosamente (nessuna uscita) su errori del server

Ma non c'è modo di ottenere sia il codice di ritorno non zero ** E** il corpo di risposta in stdout.

Basato sulla risposta di pvandenberk e quest'altro trucco molto utile imparato su SO , ecco un workaround :

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
}
``` &001 


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[.
11
11
11
2015-07-15 20:08:53 +0000

Questo invierà una richiesta all'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
9
9
9
2016-01-07 08:36:07 +0000

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
6
6
2016-11-21 11:28:27 +0000

Usate il seguente comando cURL e tubatelo 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: Seguire le intestazioni Location:

Ecco un link a codici di stato HTTP .

Eseguire dalla riga di comando. Questo ricciolo funziona in modalità silenziosa, segue qualsiasi reindirizzamento, ottiene le intestazioni HTTP. grep stamperà il codice di stato HTTP in uscita standard.

5
5
5
2017-03-08 05:12:46 +0000
curl -so -i /dev/null -w "%{http_code}" http://www.any_example.com

Questo restituirà le seguenti informazioni:

  1. dati di risposta, se qualche dato è restituito da API come errore
  2. codice di stato
4
4
4
2016-06-23 10:37:18 +0000

Ecco qualche comando curl che sta usando GET e che restituisce il codice HTTP.

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

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

curl -I http://www.example.org
4
4
4
2018-04-01 17:21:59 +0000

Un esempio di come utilizzare i codici di risposta. Lo uso per scaricare nuovamente i database Geolite solo se sono cambiati (-z) e anche in seguito a 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
3
3
2017-10-07 07:32:50 +0000

L'OP vuole conoscere il codice di stato. Spesso quando si scarica un file si vuole anche avere un'idea delle sue dimensioni, quindi utilizzo prima curl per mostrare il codice di stato e le dimensioni del file e poi spengo il file verboso e diretto al luogo e al nome che voglio:

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

Poi aspetto il completamento di curl

wait ${!}

prima di eseguire il comando successivo. Quanto sopra, se usato in uno script di molti comandi come quello precedente, dà una bella 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. Questo permette di salvare i file in una struttura di nomi sensata quando li si d/l con curl. Si noti anche che -s e -S usati insieme silenziano l'output ma mostrano errori. Si noti anche che -R cerca di impostare il timestamp del file su quello del file web.

La mia risposta si basa su ciò che @pvandenberk ha suggerito originariamente, ma in aggiunta salva effettivamente il file da qualche parte, invece di indirizzarlo semplicemente a /dev/null.

1
1
1
2019-06-04 08:08:22 +0000

Dividere il contenuto dell'uscita in stdout e il codice di stato HTTP in stderr:

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

Se si desidera solo il codice di stato HTTP per stderr, si può usare --silent:

$ (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>
...

Il flusso desiderato può poi essere scelto reindirizzando quello indesiderato a /dev/null:

&001

Notare che per il secondo reindirizzamento per comportarsi come desiderato, è necessario eseguire il comando curl nel sottoguscio.