Posso far fallire cURL con un exitCode diverso da 0 se il codice di stato HTTP non è 200?


239

Ho sempre pensato che quando curl ha ricevuto una risposta HTTP 500, stava restituendo un codice di uscita che significava fallimento (! = 0), ma sembra che non sia così.

Esiste un modo per far fallire cURL con un exitCode diverso da 0 se il codice di stato HTTP non è 200? So di poterlo utilizzare, -w "%{http_code}"ma questo lo inserisce in STDOUT, non come codice di uscita (inoltre, sono anche interessato a catturare l'output, che non voglio reindirizzare a un file, ma allo schermo).

Risposte:


264

curl --fail fa parte di ciò che vuoi:

da man curl:

-f, --fail

(HTTP) Errore silenzioso (nessun output) su errori del server. Questo viene fatto principalmente per abilitare meglio gli script ecc per gestire meglio i tentativi falliti. In casi normali quando un server HTTP non riesce a consegnare un documento, restituisce un documento HTML che lo afferma (che spesso descrive anche perché e altro). Questo flag impedisce all'arricciatura di emetterlo e restituisce l'errore 22.

Questo metodo non è sicuro e ci sono occasioni in cui i codici di risposta non riusciti passano attraverso, specialmente quando è coinvolta l'autenticazione (codici di risposta 401 e 407).

Ma blocca l'output sullo schermo.


2
Quindi quali parti fa e non fa?
rogerdpack,

5
@rogerdpack tl; dr restituisce un valore diverso da zero quando rileva una risposta errata, ma non consentirebbe a OP di catturare la risposta
rampion

3
Questo non rileva HTTP 301 Move Permanently. ricciolo ha ancora dato il codice di uscita 0.
wisbucky

4
@wisbucky 301 non è un errore, è un codice di stato di reindirizzamento. Gli errori sono codici di stato 4xx e 5xx.
M. Justin

1
@wisbucky per uscire da zero su codici di errore HTTP e gestire i reindirizzamenti HTTP utilizzare correttamente curl -f -Le vedere questa domanda per i dettagli su cosa -Lfa.
Noah Sussman,

81

Se vuoi solo visualizzare i contenuti della pagina arricciata, puoi farlo:

STATUSCODE=$(curl --silent --output /dev/stderr --write-out "%{http_code}" URL)

if test $STATUSCODE -ne 200; then
    # error handling
fi

Questo scrive il contenuto della pagina su STDERR mentre scrive il codice di stato HTTP su STDOUT, quindi può essere assegnato alla variabile STATUSCODE .


3
Che ne dite se voglio produrre la risposta in caso di errore (non 200) , ma restituire un 0codice non status dallo script?
Justin,

2
@Justin: che dire if [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fi?
ghoti,

4
@ghoti: sono supportati solo i codici di uscita a 8 bit senza segno, quindi ciò potrebbe creare un po 'di confusione.
Dennis,

3
Ah, giusto - e i codici verranno inseriti a 8 bit, quindi l'errore 404 diventa il valore di uscita 148, 500 diventa 244. Davvero confuso! :-)
ghoti,

7
Come leggera variazione, questo cattura il codice in una variabile mentre reindirizza la risposta a stdout, non stderr: { code=$(curl ... as above ...); } 2>&1il trucco è { ... } 2>&1che consente il reindirizzamento, senza generare una shell diversa come ( ... )farebbe.
Tobia,

31

Sono stato in grado di farlo utilizzando una combinazione di flag:

curl --silent --show-error --fail URL

--silent nasconde l'avanzamento e l'errore
--show-error mostra il messaggio di errore nascosto da --silent
--fail restituisce un codice di uscita> 0 quando la richiesta fallisce


5
Questo non mostra la risposta del server. Non sono OP ma sospetto che volesse vedere qualsiasi messaggio di errore dal server restituito nel corpo. Oltre a --silent --show-error --failfunziona come solo -f/--fail.
rifiuti il

1
In realtà, --failrestituisce il codice di uscita 22, come documentato .
Domande Quolonel del

2
@wisbucky 301 non è un errore, è un codice di stato di reindirizzamento. Gli errori sono codici di stato 4xx e 5xx.
M. Justin

4
Per essere onesti con @wisbucky, la domanda originale afferma "[...] se il codice di stato HTTP non è 200" . Nessuna menzione di "errore" in nessun luogo prima.
Ken,

2
@ M.Justin Secondo la pagina man di curl: questo metodo non è a prova di errore e ci sono occasioni in cui i codici di risposta non riusciti passano attraverso, specialmente quando è coinvolta l'autenticazione (codici di risposta 401 e 407).
youfu

0

Sì, c'è un modo per farlo, ma è tutt'altro che ovvio in quanto comporta 3 opzioni di arricciatura:

curl -s --fail --show-error https://httpbin.org/status/200 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/401 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/404 > /dev/null
curl -s --fail --show-error https://bleah-some-wrong-host > /dev/null

Questo assicura che il successo (0) si verifica solo quando il ricciolo ci finisce con il 2xxcodice di ritorno finale e che stdoutottiene il corpo e che tutti gli errori verranno visualizzati su stderr.

Nota che la documentazione di arricciatura potrebbe confonderti un po 'perché indica che --fail potrebbe avere successo per circa 401 codici. Basato su test che non sono veri, almeno non quando usati con --show-error allo stesso tempo.

Finora non sono riuscito a trovare alcun caso in cui il ricciolo restituirà successo quando non è stato un http-successo con queste opzioni.


1
è essenzialmente la stessa risposta di Ricardo Souza?
Knocte
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.