676

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

15 ответов15

714

Более конкретный способ распечатать только код состояния 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/
426

Это должно работать для вас, если веб-сервер может отвечать на запросы HEAD (это не будет выполнять GET):

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

Кроме того, чтобы позволить cURL следовать перенаправлениям (статусы 3xx), добавьте -L.

192

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

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
165

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

curl -i http://example.org

Преимущество -i том, что он работает и с -X POST .

58

Если вы хотите записать код состояния 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 отметил в комментариях ниже.

29

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

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

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

13

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

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

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

11

Это отправит запрос на URL, получит только первую строку ответа, разделит его на блоки и выберет вторую.

Содержит код ответа

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2
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]'
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 [.

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

Это вернет следующую информацию:

  1. данные ответа, если какие-либо данные возвращаются API, как ошибка
  2. код состояния
4

Вот некоторая команда curl, которая использует GET и возвращает код HTTP.

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

Помните, что в приведенном ниже подходе используется HEAD , который работает быстрее, но может не работать на некоторых менее веб-HTTP-серверах.

 curl -I http://www.example.org
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 должен следовать полный путь к файлу + имя файла. Таким образом, это позволяет вам сохранять файлы в разумной структуре имен, когда вы добавляете их с помощью curl. Также обратите внимание, что -s и -S, используемые вместе, отключают вывод, но показывают ошибки. Также обратите внимание, что -R пытается установить временную метку файла для веб-файла.

Мой ответ основан на том, что изначально предлагал @pvandenberk, но кроме того, он фактически сохраняет файл где-то, а не просто указывает на /dev /null.

3

Пример использования кодов ответов. Я использую это для повторной загрузки баз 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 и передайте ее в 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 на стандартный вывод.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .