Чи можу я зробити так, щоб CURL провалився з вихідним кодом, відмінним від 0, якщо код статусу HTTP не дорівнює 200?


239

Я завжди припускав, що коли curl отримав відповідь HTTP 500, він повертав код виходу, що означав збій (! = 0), але, здається, це не так.

Чи можу я змусити збити cURL з відхиленням кодом, відмінним від 0, якщо код статусу HTTP не 200? Я знаю, що можу використовувати, -w "%{http_code}"але це ставить його в STDOUT, не як код виходу (крім того, я також зацікавлений у захопленні виводу, який я не хочу перенаправляти на файл, а на екран).

Відповіді:


263

curl --fail робить частину того, що ви хочете:

від man curl:

-f, --fail

(HTTP) Збій мовчки (взагалі немає виводу) на помилках сервера. Здебільшого це робиться для того, щоб краще включити сценарії тощо, щоб краще вирішити невдалі спроби. У звичайних випадках, коли сервер HTTP не вдається доставити документ, він повертає HTML-документ із зазначенням цього (що часто також описує, чому і багато іншого). Цей прапор запобіжить виводу цього завитка та поверне помилку 22.

Цей метод не є безпечним для відмов, і бувають випадки, коли коди відповідей будуть невдалі, особливо якщо йдеться про автентифікацію (коди відповідей 401 та 407).

Але це блокує вихід на екран.


2
Отже, які його частини це робить, а не робити?
rogerdpack

5
@rogerdpack tl; dr він повертається ненульовим, коли виявляє погану реакцію, але це не дозволило ОП захопити відповідь
чемпіон

3
Це не сприймає постійне переміщення HTTP 301. curl все ж дав вихідний код 0.
wisbucky

4
@wisbucky 301 - це не помилка, це код статусу перенаправлення. Помилки - це коди стану 4xx та 5xx.
М. Джастін

1
@wisbucky, щоб вийти з ненульових кодів помилок HTTP та керувати перенаправленнями HTTP правильно використовувати curl -f -Lта переглянути це питання для детальної інформації про те, що -Lробить.
Ной Суссман

81

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

STATUSCODE=$(curl --silent --output /dev/stderr --write-out "%{http_code}" URL)

if test $STATUSCODE -ne 200; then
    # error handling
fi

Це записує вміст сторінки в STDERR під час запису коду статусу HTTP в STDOUT, тому він може бути призначений змінній STATUSCODE .


3
Як щодо того, якщо я хочу вивести відповідь на помилку (не 200) , але повернути 0код не статусу зі сценарію?
Джастін

2
@Justin: А що if [ "$statuscode" -ne 200 ]; then exit "$statuscode"; fi?
ghoti

4
@ghoti: Підтримуються лише неподписані 8-бітні коди виходу, так що вони можуть стати трохи заплутаними.
Денніс

3
Ага, правильно - і коди обернуться на 8 біт, тому помилка 404 стає значенням виходу 148, 500 стає 244. Дійсно заплутано! :-)
ghoti

7
Як незначна зміна, це фіксує код у змінній, перенаправляючи відповідь на stdout, а не stderr: { code=$(curl ... as above ...); } 2>&1хитрість полягає в { ... } 2>&1тому, що дозволяє перенаправляти, не породжуючи іншу оболонку, як ( ... )би.
Тобія

31

Я зміг це зробити за допомогою комбінації прапорів:

curl --silent --show-error --fail URL

--silent приховує хід і помилку -
show-error показує повідомлення про помилку, приховане --silent
--fail повертає код виходу> 0, коли запит не вдається


5
Це не відображає відповідь сервера. Я не ОП, але я підозрюю, що він хотів побачити повідомлення про помилку з сервера, яке повертається в тілі. До того ж --silent --show-error --failтвори такі ж, як і просто -f/--fail.
відходи

1
Насправді --failповертає код виходу 22, як це зафіксовано .
питання Quolonel

2
@wisbucky 301 - це не помилка, це код статусу перенаправлення. Помилки - це коди стану 4xx та 5xx.
М. Джастін

4
Справедливість до @wisbucky, в початковому запитанні зазначено "[...] якщо код статусу HTTP не 200" . Ніякої згадки про "помилку" ніде раніше.
кен

2
@ M.Justin За даними сайту curl: Цей метод не є безпечним, і бувають випадки, коли невдалі коди відповідей будуть прослизати, особливо якщо це стосується автентифікації (коди відповідей 401 і 407).
youfu

0

Так, є спосіб це зробити, але далеко не очевидний, оскільки він включає 3 варіанти завивки:

curl -s --fail --show-error https://httpbin.org/status/200 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/401 > /dev/null
curl -s --fail --show-error https://httpbin.org/status/404 > /dev/null
curl -s --fail --show-error https://bleah-some-wrong-host > /dev/null

Це запевняє, що успіх (0) трапляється лише тоді, коли curl закінчиться з кінцевим 2xxкодом повернення і stdoutотримає тіло, і що будь-які помилки відображатимуться на stderr.

Зауважте, що документація на curl може вас трохи заплутати, оскільки вона згадує, що --fail може досягти успіху за деякими 401 кодами. На основі тестів, що не відповідає дійсності, принаймні, не одночасно, коли використовується з - show-error.

Поки що мені не вдалося знайти жодного випадку, коли curl поверне успіх, якщо це не http-успіх з цими параметрами.


1
це по суті та сама відповідь, як і Рікардо Суза?
knocte
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.