Я использую curl
в командной строке в Linux для выдачи HTTP-запросов. Тела ответа распечатываются в стандартном формате, что нормально, но я не вижу на странице руководства, как получить curl для печати кода состояния HTTP из ответа (404, 403 и т.д.). Это возможно?
15 ответов
Более конкретный способ распечатать только код состояния 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/
Это должно работать для вас, если веб-сервер может отвечать на запросы HEAD (это не будет выполнять GET
):
curl -I http://www.example.org
Кроме того, чтобы позволить cURL следовать перенаправлениям (статусы 3xx), добавьте -L.
Если вы хотите увидеть заголовок и результат, вы можете использовать подробную опцию:
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
Вы можете напечатать код состояния, в дополнение ко всем заголовкам, выполнив следующие действия:
curl -i http://example.org
Преимущество -i
том, что он работает и с -X POST
.
Если вы хотите записать код состояния HTTP в переменную, но при этом перенаправить содержимое в STDOUT, вы должны создать два STDOUT. Вы можете сделать это с помощью подстановки процесса>() и подстановки команды $().
Сначала создайте файловый дескриптор 3
для текущего процесса 'STDOUT с exec 3>&1
.
Затем используйте параметр -o
curl, чтобы перенаправить содержимое ответа во временное fifo с помощью подстановки команд, а затем в рамках этой подстановки команд перенаправить вывод обратно в дескриптор 3
файла STDOUT текущего процесса с помощью -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 отметил в комментариях ниже.
Переопределить вывод curl:
curl -sw '%{http_code}' http://example.org
Может использоваться с любым типом запроса.
ТОЛЬКО код состояния
[0]$ curl -LI http://www.example.org -o /dev/null -w '%{http_code}\n' -s
[0]$ 200
Все заслуги в этом GIST
Это отправит запрос на URL, получит только первую строку ответа, разделит его на блоки и выберет вторую.
Содержит код ответа
curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
Для запроса 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]'
Это болезненный curl --fail
ограничение. От man curl
:
-f, --fail (HTTP) Fail молча (без вывода вообще) при ошибках сервера
Но нет никакого способа получить и ненулевой код возврата, и тело ответа в 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 [.
curl -so -i /dev/null -w "%{http_code}" http://www.any_example.com
Это вернет следующую информацию:
- данные ответа, если какие-либо данные возвращаются API, как ошибка
- код состояния
Вот некоторая команда curl, которая использует GET
и возвращает код HTTP.
curl -so /dev/null -w '%{response_code}' http://www.example.org
Помните, что в приведенном ниже подходе используется HEAD
, который работает быстрее, но может не работать на некоторых менее веб-HTTP-серверах.
curl -I http://www.example.org
ОП хочет знать код статуса. Часто при загрузке файла вы также хотите почувствовать его размер, поэтому я сначала использую 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 должен следовать полный путь к файлу + имя файла. Таким образом, это позволяет вам сохранять файлы в разумной структуре имен, когда вы добавляете их с помощью curl. Также обратите внимание, что -s и -S, используемые вместе, отключают вывод, но показывают ошибки. Также обратите внимание, что -R пытается установить временную метку файла для веб-файла.
Мой ответ основан на том, что изначально предлагал @pvandenberk, но кроме того, он фактически сохраняет файл где-то, а не просто указывает на /dev /null.
Пример использования кодов ответов. Я использую это для повторной загрузки баз 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
Используйте следующую команду cURL и передайте ее в grep следующим образом:
$ curl -I -s -L http://example.com/v3/get_list | grep "HTTP/1.1"
Вот что делает каждый флаг:
-I
: Показать только заголовки ответа-s
: Silent - не показывать индикатор выполнения-L
: СледуйтеLocation:
заголовки
Вот ссылка на коды состояния HTTP.
Запустите из командной строки. Этот curl работает в режиме без вывода сообщений, следует за любыми перенаправлениями, получает заголовки HTTP. grep выведет код состояния HTTP на стандартный вывод.