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

Pobierz curl do wyjścia kodu stanu HTTP?

Używam curl w linii poleceń na Linuksie do wydawania żądań HTTP. Ciała odpowiedzi są drukowane standardowo, co jest w porządku, ale nie widzę na stronie man jak uzyskać curl do wydrukowania kodu statusu HTTP z odpowiedzi (404, 403 itp.). Czy jest to możliwe?

Odpowiedzi (16)

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

Bardziej specyficzny sposób na wydrukowanie just kodu statusu HTTP to coś w rodzaju:

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

O wiele łatwiejsza praca w skryptach, ponieważ nie wymaga żadnego parsowania :-)

Parametr -I może być dodany w celu poprawy wydajności obciążenia odpowiedzi. Parametr ten wymaga jedynie podania statusu/nałówków odpowiedzi, bez konieczności pobierania treści odpowiedzi.

Uwaga: %{http_code} zwraca w pierwszej linii ładunek HTTP

tj.

572
572
572
2011-04-18 10:56:02 +0000

To powinno zadziałać dla Ciebie if serwer www jest w stanie odpowiedzieć na żądania HEAD (to nie wykona GET):

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

Jako dodatek, aby cURL podążał za przekierowaniami (3xx statusów) dodać -L.

237
237
237
2012-05-03 04:28:44 +0000

Jeśli chcesz zobaczyć nagłówek, jak również wynik, możesz użyć opcji czasownika:

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

W nagłówku pojawi się status. Np.

< 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

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

curl -i http://example.org

Dobrą stroną -i jest to, że współpracuje również z -X POST.

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

Jeśli chcesz przechwycić kod statusu HTTP w zmiennej, ale mimo to przekierować zawartość do STDOUT, musisz utworzyć dwa STDOUTs. Możesz to zrobić z podstawianie procesu >() i podstawianie komend $() .

Najpierw utwórz deskryptor pliku 3 dla aktualnego procesu’ STDOUT z exec 3>&1.

Następnie, użyj opcji curl’s -o do przekierowania zawartości odpowiedzi na tymczasowe fifo przy pomocy podstawiania poleceń, a następnie w ramach tego podstawiania poleceń, przekieruj wyjście z powrotem do bieżącego procesu STDOUT deskryptor pliku 3 z -o >(cat >&3).

Składanie tego wszystkiego razem w 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 nie działa to w /bin/sh jak SamK zauważył w komentarzach poniżej .

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

Zdefiniowanie na nowo wydajności samozwijania się papieru:

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

Może być użyty z każdym rodzajem żądania.

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

Kod statusu Tylko

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

Wszystkie notyfikacje do tego GIST

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

Jest to bolesne ograniczenie curl --fail. From man curl :

-f, –fail (HTTP) Fail quiet (no output at all) on server errors

But there is no way to get both the non-zero return code AND the response body in stdout.

Na podstawie odpowiedzi pvandenberk i tej innej bardzo użytecznej sztuczki nauczonej 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 jak curl, ale zwróci 127 (kod zwrotny nieużywany przez curl) w przypadku kodu HTTP w zakresie [400, 600[.

11
11
11
2015-07-15 20:08:53 +0000

Spowoduje to wysłanie zapytania do url, otrzymanie tylko pierwszej linii odpowiedzi, podzielenie jej na bloki i wybranie drugiej.

Zawiera kod odpowiedzi

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
9
9
9
2016-01-07 08:36:07 +0000

Dla wniosku o POST zadziałały:

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

Użyj następującej komendy cURL i potuj ją, aby grepować tak jak:

$ curl -I -s -L http://example.com/v3/get\_list | grep “HTTP/1.1”

Oto co robi każda flaga:

  • -I: Show only response headers
  • -s: Silent - Nie pokazuj paska postępu
  • -L: Follow Location: headers

Here is a link to HTTP status codes .

Run from the command line. To curl działa w trybie cichym, śledzi wszelkie przekierowania, pobiera nagłówki HTTP. grep wydrukuje kod statusu HTTP na standardowe wyjście.

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

To zwróci następujące informacje:

  1. dane odpowiedzi, jeśli jakieś dane są zwracane przez API jak błąd
  2. kod statusu
4
4
4
2016-06-23 10:37:18 +0000

Oto kilka komend curl, które używają GET i które zwracają kod HTTP.

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

Należy pamiętać, że poniższe podejście wykorzystuje HEAD, który jest szybszy, ale może nie działać dobrze z niektórymi mniej zgodnymi serwerami HTTP.

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

Przykładowy sposób użycia kodów odpowiedzi. Używam go do ponownego pobrania baz danych Geolitu tylko wtedy, gdy uległy one zmianie (-z), a także po przekierowaniach (-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

OP chce znać kod statusu. Często przy pobieraniu pliku chcemy również poczuć jego rozmiar, więc najpierw używam curl'a, aby pokazać kod statusu i rozmiar pliku, a następnie wyłączam verbose i kieruję plik do miejsca i nazwy, której chcę:

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

Następnie czekam na zakończenie curl'a

wait ${!}

zanim uruchomię kolejną komendę. Powyższe w przypadku użycia w skrypcie wielu komend jak powyżej daje ładną odpowiedź jak:

http: 200 42824

http: 200 34728

http: 200 35452

Należy pamiętać, że -o w curl należy podać pełną ścieżkę do pliku + nazwę pliku. Pozwala to na zapisanie plików w sensownej strukturze nazw, gdy d/l je z curl. Zauważ również, że -s i -S używane razem wyciszają wyjście, ale nie pokazują błędów. Zauważ również, że -R próbuje ustawić znacznik czasowy pliku na plik internetowy.

Moja odpowiedź jest oparta na tym, co @pvandenberk pierwotnie sugerował, ale w dodatku faktycznie zapisuje plik gdzieś, zamiast tylko kierować się do /dev/null.

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

Split output content to stdout and HTTP status code to stderr:

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

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

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

Pożądany strumień można następnie wybrać przekierowując niepożądany 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>
...

Uwaga, że aby drugie przekierowanie zachowało się jak należy, musimy uruchomić polecenie curl w podpowłoce.