Как оценить коды ответов HTTP из bash/shell script?
У меня такое ощущение, что я пропускаю очевидное, но не удалось с man [curl|wget]
или google ( "http" делает такой плохой поисковый запрос). Я ищу быстрое и грязное исправление для одного из наших веб-серверов, который часто терпит неудачу, возвращая код состояния 500 с сообщением об ошибке. Как только это произойдет, его необходимо перезапустить.
Как трудно найти основную причину, мы стремимся к быстрому исправлению, надеясь, что этого будет достаточно, чтобы сократить время, пока мы не сможем его исправить (услуга не требует высокой доступности)
Предлагаемое решение - создать задание cron, которое выполняется каждые 5 минут, проверяя http://localhost:8080/. Если это возвращается с кодом состояния 500, веб-сервер будет перезапущен. Сервер перезапустится менее чем за минуту, поэтому нет необходимости проверять, что перезапуск уже запущен.
Сервер, о котором идет речь, является минимальной установкой ubuntu 8.04 с достаточным количеством пакетов, установленных для запуска того, что в настоящее время требуется. Нет жесткого требования выполнить задачу в bash, но я бы хотел, чтобы она работала в такой минимальной среде, не устанавливая никаких дополнительных интерпретаторов.
(Я достаточно знаком с написанием сценариев о том, что команды/параметров для назначения кода состояния http для переменной среды будет достаточно - это то, что я искал и не смог найти.)
Ответы
Ответ 1
Я не проверял это на коде 500, но он работает на других, таких как 200, 302 и 404.
response=$(curl --write-out %{http_code} --silent --output /dev/null servername)
В соответствии с предложением @ibai добавьте --head
, чтобы сделать запрос только для HEAD. Это сэкономит время при успешном извлечении, поскольку содержимое страницы не будет передано.
Ответ 2
curl --write-out "%{http_code}\n" --silent --output /dev/null "$URL"
работает. Если нет, вам нужно нажать "вернуться", чтобы просмотреть сам код.
Ответ 3
Хотя принятый ответ является хорошим ответом, он игнорирует сценарии сбоев. curl
вернет 000
, если в запросе произошла ошибка или произошел сбой соединения.
url='http://localhost:8080/'
status=$(curl --head --location --connect-timeout 5 --write-out %{http_code} --silent --output /dev/null ${url})
[[ $status == 500 ]] || [[ $status == 000 ]] && echo restarting ${url} # do start/restart logic
Примечание: это выходит за рамки запрошенной проверки статуса 500
, чтобы также подтвердить, что curl
может даже подключиться к серверу (то есть возвращает 000
).
Создайте из него функцию:
failureCode() {
local url=${1:-http://localhost:8080}
local code=${2:-500}
local status=$(curl --head --location --connect-timeout 5 --write-out %{http_code} --silent --output /dev/null ${url})
[[ $status == ${code} ]] || [[ $status == 000 ]]
}
Тест на получение 500
:
failureCode http://httpbin.org/status/500 && echo need to restart
Проверка получения ошибки/сбоя подключения (т.е. 000
):
failureCode http://localhost:77777 && echo need to start
Тест не получен 500
:
failureCode http://httpbin.org/status/400 || echo not a failure
Ответ 4
Мне нужно было что-то быстро продемонстрировать сегодня и придумал это. Думаю, я бы разместил его здесь, если кому-то нужно что-то похожее на запрос OP.
#!/bin/bash
status_code=$(curl --write-out %{http_code} --silent --output /dev/null www.bbc.co.uk/news)
if [[ "$status_code" -ne 200 ]] ; then
echo "Site status changed to $status_code" | mail -s "SITE STATUS CHECKER" "[email protected]" -r "STATUS_CHECKER"
else
exit 0
fi
Это приведет к отправке оповещения по электронной почте о каждом изменении состояния с 200, поэтому он немой и потенциально жадный. Чтобы улучшить это, я бы посмотрел на цикл через несколько кодов состояния и выполнение различных действий, зависящих от результата.
Ответ 5
С netcat и awk вы можете обрабатывать ответ сервера вручную:
if netcat 127.0.0.1 8080 <<EOF | awk 'NR==1{if ($2 == "500") exit 0; exit 1;}'; then
GET / HTTP/1.1
Host: www.example.com
EOF
apache2ctl restart;
fi
Ответ 6
Следовать за переадресацией 3XX и кодами ответов на печать для всех запросов:
HTTP_STATUS="$(curl -IL --silent example.com | grep HTTP )";
echo "${HTTP_STATUS}";
Ответ 7
Еще один вариант:
status=$(curl -sS -I https://www.healthdata.gov/user/login 2> /dev/null | head -n 1 | cut -d' ' -f2)
status_w_desc=$(curl -sS -I https://www.healthdata.gov/user/login 2> /dev/null | head -n 1 | cut -d' ' -f2-)
Ответ 8
Здесь идет длинный, но понятный - script, вдохновленный решением nicerobot, который запрашивает только заголовки ответов и избегает использования IFS, как предлагается здесь. Он выводит сообщение об отказе, когда он встречает ответ >= 400. Это эхо может быть заменено на bounce- script.
# set the url to probe
url='http://localhost:8080'
# use curl to request headers (return sensitive default on timeout: "timeout 500"). Parse the result into an array (avoid settings IFS, instead use read)
read -ra result <<< $(curl -Is --connect-timeout 5 "${url}" || echo "timeout 500")
# status code is second element of array "result"
status=${result[1]}
# if status code is greater than or equal to 400, then output a bounce message (replace this with any bounce script you like)
[ $status -ge 400 ] && echo "bounce at $url with status $status"
Ответ 9
это может помочь оценить статус http
var=`curl -I http://www.example.org 2>/dev/null | head -n 1 | awk -F" " '{print $2}'`
echo http:$var
Ответ 10
Чтобы добавить к комментарию @DennisWilliamson выше:
@VaibhavBajpai: Попробуйте это: response = $(curl --write-out\n% {http_code} --silent --output - servername) - последней строкой в результате будет код ответа
Затем вы можете проанализировать код ответа из ответа, используя следующее: где X может означать регулярное выражение, чтобы пометить конец ответа (используя здесь пример json)
X='*\}'
code=$(echo ${response##$X})
См. Удаление подстроки: http://tldp.org/LDP/abs/html/string-manipulation.html
Ответ 11
мне не понравились ответы, которые смешивают данные со статусом.
нашел это:
Вы добавляете флаг -f для сбоя curl и выбираете код состояния ошибки из стандартного var status: $?
https://unix.stackexchange.com/info/204762/return-code-for-curl-used-in-a-command-substitution
я не знаю, подходит ли он для каждого сценария здесь, но кажется, что он соответствует моим потребностям, и я думаю, что намного легче работать с