Як отримати curl для виведення коду статусу HTTP?


798

Я використовую curlв командному рядку в Linux для видачі HTTP-запитів. Органи відповіді друкуються стандартним способом, що добре, але я не бачу на сторінці людини, як згорнутись, щоб надрукувати код статусу HTTP з відповіді (404, 403 тощо). Чи можливо це?


Що стосується мене, то з посібника я бачу, як отримати код статусу HTTP, але варіант -w не працює. Я повідомив про помилку в Apple.
Ніколя Барбулеско

19
-iПрапор, як curl -i https://www.example.com/, ймовірно , що ви хочете, згідно superuser.com/a/514798/190188
каркати

Чому б не просто щось подібне curl -IL http://www.example.com | grep "^HTTP\/"?
St3an

Не для майбутнього самоврядування: відповідь, яку ви хочете, - це, мабуть, Кирило Девід (зараз на 4-й позиції)
WhiteHotLoveTiger

Відповіді:


525

Це повинно працювати для вас, якщо веб-сервер здатний відповідати на запити HEAD (це не буде виконувати a GET):

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

Як додаток, щоб дозволити cURL слідувати за перенаправленнями (3хх статусів) додати -L.


154
Примітка: curl -Iчи запит HTTP HEAD, який може бути проблематичним для тестування коду статусу HTTP для деяких серверів та служб веб-додатків
Jay Taylor

16
І щоб отримати лише номер статусу, передайте його доhead -n 1|cut -d$' ' -f2
Benubird

33
Не забудьте перенаправити потік помилок Curl в: curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2. Додайте -L для згортання, якщо вам потрібен остаточний статус після переадресації.
Аарон Бленкуш

1
Після переадресації після виконання лише запиту HEAD може спричинити цікаву поведінку, залежно від того, як програмується програма.
Скотт Макінтайр

31
curl -I -X GETнадішле GET-запит, але дасть той самий вихід.
джиггі

835

Більш конкретний спосіб роздрукувати лише код статусу HTTP - це те, що є таким:

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

Набагато простіше працювати з сценаріями, оскільки він не вимагає розбору :-)

Параметр -Iможе бути доданий для покращення продуктивності навантаження на відповідь. Цей параметр просто запит на статус / заголовки відповіді, без тіла відповіді на завантаження.

Примітка: %{http_code} повертається на перший рядок корисного навантаження HTTP

тобто:

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

54
-w "% {http_code}" - це біт, який друкує код статусу. Ви можете додати туди новий або два рядки, щоб відокремити код від тіла (-w "\ n \ n% {http_code} \ n")
Джеффрі Мартінес

7
Нічого собі, ця /dev/nullріч працює навіть у версії Windows для скручування, яку я використовую.
Уве Кеїм

3
Я вважаю, що це завантажує весь файл, навіть якщо все йде в / dev / null, тому не ідеально підходить для перевірки коду статусу для величезних файлів. httping -c 1 -s -G -mвидає GET і не завантажує весь файл, хоча я розумію, що це питання стосується саме завивання.
RomanSt

40
FYI: -s= Не показувати хід завантаження, -o /dev/null= не показувати тіло, -w "%{http_code}"= Написати http-код відповіді для stdout після виходу.
Ajedi32

1
Чи потрібні лапки навколо "% {http_code}"?
Хакан Баба

216

Якщо ви хочете побачити заголовок, а також результат, ви можете скористатись детальною опцією:

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

26
+1 для вказівки багатослівного прапора надає додаткові деталі. Відмінно підходить для тестування програм REST.
MrOodles

8
+1 дуже простий у користуванні під час запиту POST (curl -v --дані "...")
MegaTux

1
Він навіть розбиває їх на два різні вихідні файли (деталі статусу http на stderr та тіло реакції на stdout)
Blauhirn

201

Ви можете надрукувати код статусу, окрім усіх заголовків, виконавши такі дії:

curl -i http://example.org

Хороша річ у -iтому, що вона також працює -X POST.


36
Набагато краще, ніж прийнята відповідь (яка робить запит HEAD).
neu242

10
Можливо, очевидно, але -iчи працює з будь-яким методом HTTP, а не просто GETі POST... :)
mac

3
найкраща відповідь, оскільки це робить висновок завитків як у заголовках, так і в тілі, що робить його придатним для більшості завдань при використанні у сценарії
Sarge Borsch

6
Це найкраща відповідь, і її можна використовувати разом із -s(не показувати показник прогресу чи повідомлення про помилки) та -S(не показувати повідомлення про помилки)
Джонатан Хартлі

69

Якщо ви хочете зафіксувати код статусу HTTP змінною, але все-таки перенаправити вміст на STDOUT, ви повинні створити два STDOUT. Це можна зробити за допомогою підстановки процесу> () та підстановки команд $ () .

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

Потім, з допомогою загнутого куточка -oможливості перенаправити вміст відповіді на тимчасовий ФІФО з допомогою підстановки команд, а потім в межах цієї команди підстановки, перенаправлення виведення на ваш поточний процес 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 "%{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')

Зауважте, що це не працює, /bin/shяк зазначив SamK у коментарях нижче .


5
Це серйозна вигадка ... і мені це подобається!
шпиль

3
Тепер, як, у свою чергу, можна перенаправити вихід на іншу змінну?
Roger Filmyer

1
Вихід є STDOUT, тому ви повинні мати можливість перенаправляти вихід з команди в будь-яке місце, як вам подобається звичайна команда. Я цього не перевіряв.
Гірські межі

1
Не працює з / бін / ш.
СамК

хороша відповідь, ви також можете перенаправити на справжній файл і передати його пізніше, якщо ви хочете переносити оболонки
akostadinov

32

Перевизначення виводу завитка:

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

Можна використовувати з будь-яким типом запиту.


-k (--небезпечний) переважає -s (мовчить).
Равічандра


11

Це болісне curl --failобмеження. Від man curl:

-f, --fail (HTTP) Збій мовчки (взагалі немає виводу) на помилках сервера

Але немає можливості отримати як ненульовий код повернення, так і тіло відповіді в stdout.

Виходячи з відповіді pvandenberk та цієї іншої дуже корисної хитрості, засвоєної на SO , ось такий спосіб вирішення:

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
}

Ця функція поводиться точно так само curl, але поверне 127 (код повернення, який не використовується curl) у випадку HTTP-коду в діапазоні [400, 600 [.


Погоджено, що неможливо побачити вихід помилки - це болісне обмеження в іншому випадку дуже зручного - невдалого. Як можна діагностувати збій api REST, не побачивши вихід помилки? Це так прикро, що сумка, що підтримує завивки, наполегливо наполягає на тому, щоб не надавати - помилки, але показувати помилку. github.com/curl/curl/isissue/1978
джамшид

Як зазначено в документації, він не працює для HTTP-кодів 401 та 407 :(
Logan Mzz

11

Це надішле запит на URL, отримає лише перший рядок відповіді, розділить його на блоки та вибере другий.

Він містить код відповіді

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

1
Чи можете ви пояснити, що робить цей код і як він вирішує проблему, задану ОП? Непояснений код може здатися ненадійним і небезпечним для користувачів.
bwDraco

1
Звичайно, ми надсилаємо запит на URL, отримуємо лише перший рядок відповіді, розділяємо його на блоки та вибираємо другий. Він містить код відповіді, який шукає ОП.
Філіп Спірідонов

9

Для запиту POST працювало наступне:

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

Скористайтеся наступною командою cURL і передайте її так, щоб вона схопилася так:

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

Ось що робить кожен прапор:

  • -I: Показати лише заголовки відповідей
  • -s: Silent - Не показувати панель прогресу
  • -L: Дотримуйтесь Location:заголовків

Ось посилання на коди статусу HTTP .

Запустити з командного рядка. Ця завитка працює в безшумному режимі, слідкує за будь-якими переадресаціями, отримуйте заголовки HTTP. grep виведе код статусу HTTP на стандартний вихід.


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

Це поверне наступну інформацію:

  1. дані відповіді, якщо будь-які дані повертаються API, як помилка
  2. код статусу

Це не переспрямовує. Ця існуюча відповідь краще superuser.com/a/442395/475508
cricket_007

Звичайно, ви можете також посилатися на це !!
срана

4

Ось якась команда curl, яка використовується, GETі яка повертає код HTTP.

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

Будь ласка, пам’ятайте, що застосовується нижче підхід HEAD, який є швидшим, але він може не працювати з деякими веб-серверами HTTP, що не відповідають стандартам.

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

Принаймні не працює в OS X.
Айн

Мені добре працювати на OS X High Sierra 10.13.6.
Бен Барон

4

Приклад того, як використовувати коди відповідей. Я використовую це для повторного завантаження баз даних Geolite, лише якщо вони змінилися ( -z) та також після переспрямування ( -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

ОП хоче знати код статусу. Часто під час завантаження файлу ви також хочете відчути його розмір, тому я спочатку використовую curl, щоб показати код статусу та розмір файлу, а потім вимкнути багатослівний та направити файл на потрібне місце та ім’я:

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

Потім чекаю закінчення завивки

wait ${!}

перш ніж запустити наступну команду. Вищезазначене, коли використовується в сценарії багатьох команд, як вище, дає приємну відповідь на зразок:

http: 200 42824

http: 200 34728

http: 200 35452

Зауважте, що -o в curl повинен дотримуватися повний шлях до файлу + ім'я файлу. Це дозволяє таким чином зберігати файли в структурі розумних імен, коли ви d / l їх з завитком. Також зауважте, що -s та -S, які використовуються разом, замовчують вихід, але показують помилки. Зверніть увагу також на те, що -R намагається встановити часову позначку файлу для веб-файлу.

Моя відповідь ґрунтується на тому, що спочатку запропонував @pvandenberk, але крім того, він фактично зберігає файл десь, а не просто направляє на / dev / null.


1

Розділити вихідний вміст stdoutта код статусу HTTP на stderr:

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

Якщо бажано --silentстягувати лише код статусу HTTP, можна використовувати:

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

Потім бажаний потік можна вибрати, перенаправляючи небажаний на /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>
...

Зауважимо, що для того, щоб друге перенаправлення вело себе бажано, нам потрібно виконати команду curl в нижній частині.


1
Вимагає bashзаміни процесу.
Яакко

@Bruno, я змінив приклад із superuser.com/reitions/1444693/2 , оскільки думаю, що /tmp/out /tmp/errфайли можуть викликати несподівані результати, якщо працювати паралельно.
Яакко
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.