如何评估来自bash / shell脚本的http响应代码?

我有这样的感觉,我错过了明显的,但没有成功的man [curl|wget]或谷歌(“http”使这样一个糟糕的search术语)。 我正在寻找一个快速和肮脏的修复我们的Web服务器之一,经常失败,返回错误消息的状态代码500。 一旦发生这种情况,需要重新启动。

由于根本原因似乎很难find,我们正在寻求一个快速修复,希望能够弥补时间,直到我们可以真正解决它(该服务不需要高可用性)

build议的解决scheme是创build一个每5分钟运行一次的cron作业,检查http:// localhost:8080 / 。 如果这返回与状态代码500,networking服务器将被重新启动。 服务器将在一分钟内重新启动,因此不需要检查已经运行的重新启动。

有问题的服务器是一个Ubuntu 8.04最小安装,只安装了足够的软件包来运行它当前所需的。 没有必要在bash中完成这个任务,但是我希望它能在这样一个最小的环境中运行,而不需要安装更多的解释器。

(我对脚本非常熟悉,将http状态代码分配给环境variables的命令/选项就足够了 – 这是我所查找和找不到的。)

我没有在500码上testing过,但是它在200,302和404等其他程序上都能正常工作。

 response=$(curl --write-out %{http_code} --silent --output /dev/null servername) 
 curl --write-out "%{http_code}\n" --silent --output /dev/null "$URL" 

作品。 如果没有,你必须打回来查看代码本身。

这里:

 url='http://localhost:8080/' status=$(r=(IFS=' ';$(curl -Is --connect-timeout 5 "${url}" || echo 1 500));echo ${r[1]}) [ status -eq 500 ] && bounce # assuming the bounce script is called 'bounce' 

或者把它放在一行上:

 [ 500 -eq $(r=(IFS=' ';$(curl -Is --connect-timeout 5 'http://localhost:8080/' || echo 1 500));echo ${r[1]}) ] && bounce 

为了解释,HTTP响应总是包含作为响应第一行的一部分的服务器状态,如:

 HTTP/1.1 200 OK HTTP/1.0 404 NOT FOUND 

该脚本只是使用curl对localhost:8080执行HEAD请求。 它将HTTP头转换为数组并返回第二个元素。 为了简化一些故障处理,如果HEAD在5秒内未能连接或由于某种原因curl失败,则也返回500。

使用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 

按照3XXredirect并打印所有请求的响应代码:

 HTTP_STATUS="$(curl -IL --silent example.com | grep HTTP )"; echo "${HTTP_STATUS}"; 

这可以帮助评估http状态

 var=`curl -I http://www.example.org 2>/dev/null | head -n 1 | awk -F" " '{print $2}'` echo http:$var 

这里来的啰嗦 – 但很容易理解 – 脚本,灵感来自nicerobot的解决scheme,只要求响应头,并避免使用IFS的build议在这里 。 当它遇到响应> = 400时,它会输出一个退回消息。这个回显可以被一个反弹脚本replace。

 # 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" 

添加到@DennisWilliamson评论上面:

@VaibhavBajpai:试试这个:response = $(curl –write-out \ n%{http_code} –silent –output – servername) – 结果的最后一行是响应代码

然后可以使用类似下面的内容来parsing响应中的响应代码,其中X可以表示一个正则expression式来标记响应的结束(在此使用json示例)

 X='*\}' code=$(echo ${response##$X}) 

请参阅删除子串: http : //tldp.org/LDP/abs/html/string-manipulation.html

另一个变化:

 status=$(curl -I https://www.healthdata.gov/user/login 2> /dev/null | head -n 1 | cut -d ' ' -f 2) 

我需要迅速演示一些东西,并提出这个问题。 以为我会把它放在这里,如果有人需要类似的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" "my_email@email.com" -r "STATUS_CHECKER" else exit 0 fi 

这将发送一个电子邮件警报,每个州从200变化,所以它是愚蠢的,可能是贪婪的。 为了改善这一点,我会考虑循环几个状态代码,并根据结果执行不同的操作。