Як отримати 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.