Dostajesz curl do wyjścia kod stanu HTTP?


797

Korzystam curlz wiersza polecenia w systemie Linux do wysyłania żądań HTTP. Ciała odpowiedzi są wypisywane na standardowe wyjście, co jest w porządku, ale nie widzę na stronie podręcznika, jak uzyskać curl, aby wydrukować kod stanu HTTP z odpowiedzi (404, 403 itp.). czy to możliwe?


Jeśli chodzi o mnie, widzę z instrukcji, jak uzyskać kod stanu HTTP, ale opcja -w nie działa. Zgłosiłem błąd do Apple.
Nicolas Barbulesco

19
-iFlaga, jak w curl -i https://www.example.com/, jest prawdopodobnie to, co chcesz, jak na superuser.com/a/514798/190188
CAW

Dlaczego nie coś takiego curl -IL http://www.example.com | grep "^HTTP\/"?
St3an

Nie dla przyszłego siebie: odpowiedź, którą chcesz, to prawdopodobnie odpowiedź Cyryla Davida (obecnie na 4 pozycji)
WhiteHotLoveTiger

Odpowiedzi:


525

Powinno to działać dla Ciebie, jeśli serwer sieciowy jest w stanie odpowiedzieć na żądania HEAD (nie będzie to możliwe GET):

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

Dodatkowo, aby cURL śledził przekierowania (statusy 3xx), dodaj -L.


154
Uwaga: curl -Iwykonuje żądanie HEAD HTTP, które może być problematyczne przy testowaniu kodu statusu HTTP dla niektórych serwerów i usług aplikacji WWW
Jay Taylor,

16
Aby uzyskać tylko numer statusu, head -n 1|cut -d$' ' -f2
przesuń

33
Nie zapomnij przekierować stderr Curl za: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Dodaj -L, aby zawinąć, jeśli potrzebujesz ostatecznego statusu po przekierowaniach.
Aaron Blenkush

1
Śledzenie przekierowania po wykonaniu żądania HEAD może spowodować interesujące zachowanie, w zależności od sposobu zaprogramowania aplikacji.
Scott McIntyre

31
curl -I -X GETwyśle ​​żądanie GET, ale da to samo wyjście.
jiggy

835

Bardziej konkretnym sposobem na wydrukowanie tylko kodu stanu HTTP jest coś w stylu:

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

O wiele łatwiej jest pracować ze skryptami, ponieważ nie wymaga to żadnej analizy :-)

Ten parametr -Imożna dodać, aby poprawić wydajność ładowania odpowiedzi. Ten parametr tylko żąda statusu / nagłówków odpowiedzi, bez treści odpowiedzi pobierania.

Uwaga: %{http_code} zwraca pierwszą linię ładunku HTTP

to znaczy:

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

54
-w „% {http_code}” to bit, który wypisuje kod stanu. Możesz dodać tam nowy wiersz lub dwa, aby oddzielić kod od treści (-w "\ n \ n% {http_code} \ n")
Jeffrey Martinez

7
Wow, ta /dev/nullrzecz działa nawet w wersji Windows curl, której używam.
Uwe Keim

3
Wierzę, że to pobiera cały plik, mimo że wszystko idzie do / dev / null, więc nie jest to idealne do sprawdzania kodu statusu dla dużych plików. httping -c 1 -s -G -mwydaje polecenie GET i nie pobiera całego pliku, chociaż zdaję sobie sprawę, że to pytanie dotyczy curl.
RomanSt

40
FYI: -s= Nie pokazuj postępu pobierania, -o /dev/null= nie wyświetlaj treści, -w "%{http_code}"= Napisz kod odpowiedzi http na standardowe wyjście po wyjściu.
Ajedi32,

1
Czy wymagane są cytaty wokół „% {http_code}”?
Hakan Baba

216

Jeśli chcesz zobaczyć nagłówek, a także wynik, możesz użyć opcji szczegółowej:

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

Status pojawi się w nagłówku. Na przykład

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

26
+1 za wskazanie pełnej flagi zapewnia dodatkowe szczegóły. Idealne do testowania aplikacji REST.
MrOodles

8
+1 bardzo łatwy w użyciu podczas wykonywania żądania POST (curl -v --data "...")
MegaTux

1
Dzieli je nawet na dwa różne dane wyjściowe pliku (szczegóły stanu HTTP na stderr i
treść

201

Możesz wydrukować kod stanu oprócz wszystkich nagłówków, wykonując następujące czynności:

curl -i http://example.org

Dobrą rzeczą -ijest to, że również działa -X POST.


36
Znacznie lepiej niż zaakceptowana odpowiedź (która wysyła żądanie HEAD).
neu242

10
Może to oczywiste, ale -idziała z dowolną metodą HTTP, nie tylko GETi POST... :)
mac.

3
najlepsza odpowiedź, ponieważ sprawia, że ​​curl wyświetla zarówno nagłówki, jak i
Sarge Borsch

6
To najlepsza odpowiedź i można jej używać w połączeniu z -s(nie pokazuj miernika postępu lub komunikatów o błędach) i -S(w końcu wyświetlaj komunikaty o błędach)
Jonathan Hartley

69

Jeśli chcesz przechwycić kod statusu HTTP w zmiennej, ale nadal przekierować treść do STDOUT, musisz utworzyć dwa STDOUT. Możesz to zrobić za pomocą podstawienia procesu> () i podstawienia polecenia $ () .

Najpierw utwórz deskryptor pliku 3dla bieżącego procesu „STDOUT za pomocą exec 3>&1.

Następnie użyj -oopcji curl, aby przekierować treść odpowiedzi do tymczasowego fifo za pomocą podstawienia polecenia, a następnie w ramach tego zastąpienia polecenia przekieruj dane wyjściowe z powrotem do bieżącego deskryptora pliku STDOUT za 3pomocą -o >(cat >&3).

Składając wszystko w całość bash 3.2.57(1)-release(standard dla 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')

Zauważ, że to nie działa, /bin/shjak zauważył SamK w komentarzach poniżej .


5
To poważna zręczność ... i podoba mi się!
spyle 30.01.2015

3
Jak z kolei mogę przekierować dane wyjściowe do innej zmiennej?
Roger Filmyer

1
Wyjście jest włączone STDOUT, więc powinieneś być w stanie przekierować wyjście z polecenia do dowolnego miejsca, tak jak zwykłe polecenie. Jednak tego nie testowałem.
Heath Borders

1
Nie działa z / bin / sh.
SamK

dobra odpowiedź, możesz również przekierować do prawdziwego pliku i
zakotwiczyć

32

Przedefiniuj wydajność zwijania:

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

Może być używany z dowolnym rodzajem żądania.


-k (--insecure) zastępuje -s (cichy).
Ravichandra

16

TYLKO kod statusu

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

Wszystkie zasługi dla tego GIST


11

To bolesne curl --failograniczenie. Od man curl:

-f, --fail (HTTP) Błąd cicho (brak danych wyjściowych) w przypadku błędów serwera

Ale nie ma sposobu, aby uzyskać zarówno niezerowy kod powrotu ORAZ treść odpowiedzi na standardowe wyjście.

W oparciu o odpowiedź pvandenberka i tę inną bardzo przydatną sztuczkę, której nauczyliśmy się na SO , oto obejście:

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
}

Ta funkcja zachowuje się dokładnie tak samo curl, ale zwróci 127 (kod powrotu nieużywany przez curl) w przypadku kodu HTTP z zakresu [400, 600 [.


Zgadzam się, że brak możliwości wyświetlenia błędu jest bolesnym ograniczeniem bardzo przydatnej w przeciwnym razie - awarii. Jak zdiagnozować awarię interfejsu API REST, nie widząc wyjścia błędu? Jest to tak niefortunne, że osoba zajmująca się utrzymywaniem loków uparcie nalega, aby nie podawać błędu „nie zadziałaj, ale pokaż”. github.com/curl/curl/issues/1978
jamshid

Jak stwierdzono w dokumentacji, nie działa dla kodów HTTP 401 i 407 :(
Logan Mzz

11

Spowoduje to wysłanie żądania do adresu URL, pobranie tylko pierwszego wiersza odpowiedzi, podzielenie go na bloki i wybranie drugiego.

Zawiera kod odpowiedzi

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

1
Czy możesz wyjaśnić, co robi ten kod i jak rozwiązuje problem zgłoszony przez PO? Niewyjaśniony kod może wydawać się niezaufany i niebezpieczny dla użytkowników.
bwDraco

1
Jasne, wysyłamy zapytanie na adres URL, otrzymujemy tylko pierwszą linię odpowiedzi, dzielimy ją na bloki i wybieramy drugą. Zawiera kod odpowiedzi, którego szuka OP.
Filip Spiridonov

9

W przypadku żądania POST działały następujące elementy:

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

Użyj następującego polecenia cURL i potokuj go, aby grep tak:

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

Oto, co robi każda flaga:

  • -I: Pokaż tylko nagłówki odpowiedzi
  • -s: Cichy - Nie pokazuj paska postępu
  • -L: Śledź Location:nagłówki

Oto link do kodów stanu HTTP .

Uruchom z wiersza poleceń. Ten curl działa w trybie cichym, podąża za wszelkimi przekierowaniami, pobiera nagłówki HTTP. grep wypisze kod stanu HTTP na standardowe wyjście.


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

Spowoduje to zwrócenie następujących informacji:

  1. dane odpowiedzi, jeśli jakiekolwiek dane są zwracane przez API, takie jak błąd
  2. Kod statusu

To nie następuje przekierowania. Ta istniejąca odpowiedź jest lepsza superuser.com/a/442395/475508
cricket_007

Jasne, możesz to również polecić !!
srana

4

Oto niektóre używane polecenie curl, GETktóre zwraca kod HTTP.

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

Pamiętaj, że stosuje się poniższe podejście HEAD, które jest szybsze, ale może nie działać dobrze z niektórymi serwerami HTTP mniej zgodnymi z Internetem.

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

Przynajmniej nie działa na OS X.
Ain

Działa dobrze dla mnie w OS X High Sierra 10.13.6.
Ben Baron

4

Przykład użycia kodów odpowiedzi. Używam tego, aby ponownie pobrać bazy danych Geolite tylko wtedy, gdy zmieniły się ( -z), a także następujące przekierowania ( -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

OP chce poznać kod statusu. Często podczas pobierania pliku chcesz też poczuć jego rozmiar, więc najpierw używam curl, aby wyświetlić kod stanu i rozmiar pliku, a następnie wyłącz pełny i bezpośredni plik do wybranego miejsca i nazwy:

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

Potem czekam na zakończenie zwijania

wait ${!}

zanim uruchomię następne polecenie. Powyższe, gdy jest użyte w skrypcie wielu poleceń takich jak powyżej, daje miłą odpowiedź, taką jak:

http: 200 42824

http: 200 34728

http: 200 35452

Zauważ, że po -o w curl musi następować pełna ścieżka do pliku + nazwa pliku. Pozwala to w ten sposób zapisywać pliki w rozsądnej strukturze nazw, gdy d / l je zwijaj. Zauważ też, że -s i -S użyte razem wyciszają wyjście, ale pokazują błędy. Zauważ też, że -R próbuje ustawić znacznik czasu pliku na taki sam jak w pliku internetowym.

Moja odpowiedź opiera się na tym, co pierwotnie sugerował @pvandenberk, ale dodatkowo faktycznie gdzieś zapisuje plik, zamiast kierować go do / dev / null.


1

Podziel zawartość wyjściową stdouti kod stanu HTTP na stderr:

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

Jeśli do stderr pożądany jest tylko kod statusu HTTP, --silentmożna użyć:

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

Żądany strumień można następnie wybrać, przekierowując niechciany strumień do /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>
...

Zauważ, że aby drugie przekierowanie działało zgodnie z potrzebami, musimy uruchomić polecenie curl w podpowłoce.


1
Wymaga bashzastąpienia procesu.
Jaakko

@Bruno, zmieniłem przykład z superuser.com/revisions/1444693/2 , ponieważ myślę, że /tmp/out /tmp/errpliki mogą powodować nieoczekiwane wyniki, jeśli zostaną uruchomione równolegle.
Jaakko
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.