Получение curl для вывода кода состояния HTTP?

736957
kdt

Я использую curlв командной строке в Linux для выдачи HTTP-запросов. Тела ответа распечатываются в стандартном формате, что нормально, но я не вижу на странице руководства, как получить curl для печати кода состояния HTTP из ответа (404, 403 и т. Д.). Это возможно?

626
Что касается меня, я могу видеть из руководства, как получить код состояния HTTP, но опция -w не работает. Я сообщил об ошибке в Apple. Nicolas Barbulesco 9 лет назад 0
Флаг `-i`, как в` curl -i https: // www.example.com / `, это, вероятно, то, что вам нужно, согласно https://superuser.com/a/514798/190188 caw 7 лет назад 10

15 ответов на вопрос

672
pvandenberk

A more specific way to print out just the HTTP status code is something along the lines of:

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

A lot easier to work with in scripts, as it doesn't require any parsing :-)

The parameter -I might be added to improve response load performance. This parameter just request for status/headers of response, without download response body. (% returns on first line of HTTP payload)

i.e.:

curl -s -o /dev/null -I -w "%" http://www.example.org/ 
-w "% " - это бит, который печатает код состояния. Вы можете добавить новую или две строки там, чтобы отделить код от тела (-w "\ n \ n% \ n") Jeffrey Martinez 10 лет назад 44
Ничего себе, эта вещь `/ dev / null` работает даже в используемой мной версии curl для Windows. Uwe Keim 9 лет назад 4
Я считаю, что это скачивает весь файл, даже если он идет в / dev / null, поэтому не идеально подходит для проверки кода состояния для больших файлов. `httping -c 1 -s -G -m` выдает GET и не загружает весь файл, хотя я понимаю, что этот вопрос специально о curl. RomanSt 8 лет назад 3
@romkyns, вы правы: первый вариант в моем ответе загружает весь файл и «сохраняет» его в `/ dev / null`, но второй вариант - т.е. тот, который использует опцию `-I` для` curl` - нет. Однако необходимо соблюдать осторожность, так как вы на самом деле не тестируете одно и то же действие: один выполняет HTTP-запрос GET, а другой - HEAD-запрос. Некоторые веб-серверы / веб-сайты будут отвечать другим кодом состояния. , даже если запрашиваемый URL-адрес точно такой же! pvandenberk 7 лет назад 0
К вашему сведению: `-s` = Не показывать ход загрузки,` -o / dev / null` = не отображать тело, `-w"% "` = Записать код ответа http на стандартный вывод после выхода. Ajedi32 7 лет назад 21
... and `-I` = * Показать только информацию о документе * Madbreaks 7 лет назад 0
Обязательны ли кавычки вокруг "% "? Hakan Baba 6 лет назад 0
Мне пришлось добавить параметр '-LI' непосредственно перед URL, чтобы иметь возможность правильно получить последний статус после перенаправления, а не '302' (на основе ответа @mahatmanich): curl -s -o / dev / null -w "% " -LI http://www.example.org/ Maksym 6 лет назад 0
Как заметил Максим, вам нужно добавить `-L`, чтобы следовать перенаправлениям, иначе ваш код состояния будет просто 302 каждый раз, когда вы сталкиваетесь со страницей, которая переместилась с 301 или 302. dragon788 5 лет назад 0
391
pberlijn

This should work for you if the web server is able to respond to HEAD requests (this will not perform a GET):

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

As an addition, to let cURL follow redirects (3xx statuses) add -L.

NB: `curl -I` выполняет HTTP-запрос HEAD, что может быть проблематично при тестировании кода состояния HTTP для некоторых серверов и служб веб-приложений. Jay Taylor 11 лет назад 123
И чтобы получить только номер статуса, направьте его в `head -n 1 | cut -d $ '' -f2` Benubird 10 лет назад 14
Не забудьте перенаправить stderr curl: `curl -I http://www.example.org 2> / dev / null | голова -n 1 | cut -d $ '' -f2`. Добавьте -L в curl, если вам нужен окончательный статус после перенаправления. Aaron Blenkush 9 лет назад 22
После перенаправления только после выполнения запроса HEAD может возникнуть интересное поведение в зависимости от того, как запрограммировано приложение. Scott McIntyre 8 лет назад 0
`curl -I -X GET` отправит запрос GET, но выдаст тот же результат. jiggy 8 лет назад 16
Вот два рабочих примера для GET и HEAD - http://superuser.com/a/1092635/3004 sorin 7 лет назад 0
Пересылка stderr в / dev / null не обязательна, если вы хотите только подавить индикатор выполнения - для этого используйте ключ `-s`. galva 7 лет назад 0
Не полезно для тестирования сервисов, которые возвращают коды состояния для других методов, кроме GET. Мол, REST услуги. Keith Tyler 7 лет назад 0
Эта команда показывает только некоторую информацию. Я не вижу своего ответа. "-i" может быть лучше. Emerald214 6 лет назад 0
182
Enrico Susatyo

Если вы хотите увидеть заголовок и результат, вы можете использовать подробную опцию:

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

Статус появится в шапке. Например

< Date: Tue, 04 Nov 2014 19:12:59 GMT < Content-Type: application/json; charset=utf-8 < Status: 422 Unprocessable Entity 
+1 за указание на подробный флаг предоставляет дополнительную информацию. Отлично подходит для тестирования приложений REST. MrOodles 11 лет назад 22
+1 очень прост в использовании при выполнении запроса POST (curl -v --data "...") MegaTux 9 лет назад 8
Он даже разделяет их на два разных выходных файла (подробности статуса http для stderr и тело ответа для stdout) Blauhirn 6 лет назад 1
157
Cyril David

Вы можете напечатать код состояния, в дополнение ко всем заголовкам, выполнив следующие действия:

curl -i http://example.org 

Хорошая вещь о -iтом, что это работает с -X POSTтакже.

Гораздо лучше, чем принятый ответ (который делает запрос HEAD). neu242 9 лет назад 23
Может быть, очевидно, но `-i` работает с ** любым ** методом HTTP, а не только с` GET` и `POST` ... :) mac 9 лет назад 7
лучший ответ, так как он делает вывод curl как заголовками, так и телом, что делает его пригодным для большинства задач при использовании в скрипте Sarge Borsch 8 лет назад 2
Это лучший ответ, и его можно использовать вместе с `-s` (не показывать индикатор прогресса или сообщения об ошибках) и` -S` (все-таки показывать сообщения об ошибках) Jonathan Hartley 7 лет назад 2
50
Heath Borders

Если вы хотите записать код состояния HTTP в переменную, но при этом перенаправить содержимое в STDOUT, вы должны создать два STDOUT. Вы можете сделать это с помощью подстановки процесса> () и подстановки команды $ () .

Сначала создайте файловый дескриптор 3для текущего процесса 'STDOUT with exec 3>&1.

Затем используйте -oопцию curl, чтобы перенаправить содержимое ответа во временный fifo с помощью подстановки команд, а затем внутри этой подстановки команд перенаправить вывод обратно в дескриптор файла текущего процесса STDOUT 3с помощью -o >(cat >&3).

Собираем все это вместе bash 3.2.57(1)-release(стандартно для 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 "%" into HTTP_STATUS # and sending the content to this command's STDOUT with -o >(cat >&3) HTTP_STATUS=$(curl -w "%" -o >(cat >&3) 'http://example.com') 

Обратите внимание, что это не работает, /bin/shкак отметил SamK в комментариях ниже .

Это серьезное занудство ... и мне это нравится! spyle 9 лет назад 3
Теперь, как, в свою очередь, я могу перенаправить вывод в другую переменную? Roger Filmyer 9 лет назад 3
Вывод находится в `STDOUT`, поэтому вы должны иметь возможность перенаправить вывод из команды в любое удобное для вас место, как обычная команда. Я не проверял это все же. Heath Borders 8 лет назад 1
Не работает с / bin / sh. SamK 5 лет назад 0
28
Grzegorz Luczywo

Переопределить вывод curl:

curl -sw '%' http://example.org 

Может использоваться с любым типом запроса.

-k (--insecure) переопределяет -s (молчит). Ravichandra 5 лет назад 0
10
Filip Spiridonov

This will send a request to url, get only the first line of the response, split it on blocks and select the second one.

It contains the response code

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2 
Можете ли вы объяснить, что делает этот код и как он решает проблему, заданную ФП? Необъяснимый код может показаться ненадежным и опасным для пользователей. bwDraco 8 лет назад 1
Конечно, мы отправляем запрос на URL, получаем только первую строку ответа, разбиваем его на блоки и выбираем вторую. Он содержит код ответа, который ищет OP. Filip Spiridonov 8 лет назад 0
10
mahatmanich

ТОЛЬКО код состояния

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

Все заслуги в этом GIST

8
zafar142003

Для запроса POST сработало следующее:

curl -w 'RESP_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]' 
7
Lucas Cimon

This is a painful curl --fail limitation. From man curl :

-f, --fail (HTTP) Fail silently (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.

Based on pvandenberk's answer and this other very useful trick learned on SO, here is a 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%\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 } 

This function behaves exactly as curl, but will return 127 (a return code non-used by curl) in case of a HTTP code in the range [400, 600[.

Согласитесь, неспособность увидеть вывод ошибки является болезненным ограничением в противном случае очень полезного --fail. Как можно диагностировать сбой REST API, не видя вывод ошибки? Это так прискорбно, что специалист по обслуживанию локонов упрямо настаивает на том, чтобы не выдавать ошибку -fail-but-show-error. https://github.com/curl/curl/issues/1978 jamshid 5 лет назад 0