繁体   English   中英

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

[英]How to evaluate http response codes from bash/shell script?

我有一种感觉,我错过了明显的东西,但没有成功使用man [curl|wget]或 google(“http”使搜索词变得如此糟糕)。 我正在寻找对我们的一个经常失败的网络服务器的快速和肮脏的修复,返回状态代码 500 并显示错误消息。 一旦发生这种情况,它需要重新启动。

由于根本原因似乎很难找到,我们的目标是快速修复,希望这足以缩短我们真正修复它的时间(服务不需要高可用性)

建议的解决方案是创建一个每 5 分钟运行一次的 cron 作业,检查http://localhost:8080/ 如果返回状态码 500,则网络服务器将重新启动。 服务器将在一分钟内重新启动,因此无需检查已在运行的重新启动。

有问题的服务器是 ubuntu 8.04 最小安装,只安装了足够的软件包来运行它当前需要的东西。 在 bash 中执行任务没有硬性要求,但我希望它在这样一个最小的环境中运行,而无需安装更多的解释器。

(我对脚本非常熟悉,将 http 状态代码分配给环境变量的命令/选项就足够了 - 这是我一直在寻找但找不到的东西。)

我没有在 500 代码上测试过这个,但它适用于 200、302 和 404 等其他代码。

response=$(curl --write-out '%{http_code}' --silent --output /dev/null servername)

请注意,应引用为 --write-out 提供的格式。 正如@ibai 所建议的,添加--head以发出仅 HEAD 请求。 这将在检索成功时节省时间,因为不会传输页面内容。

curl --write-out "%{http_code}\n" --silent --output /dev/null "$URL"

作品。 如果没有,您必须按回车键查看代码本身。

我今天需要快速演示一些东西并想出了这个。 如果有人需要类似于 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 开始的每个状态更改时发送电子邮件警报,因此它很愚蠢且可能贪婪。 为了改进这一点,我会考虑遍历几个状态代码并根据结果执行不同的操作。

尽管接受的响应是一个很好的答案,但它忽略了失败场景。 如果请求中有错误或连接失败, 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

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

要遵循 3XX 重定向并为所有请求打印响应代码:

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

这是我的实现,它比之前的一些答案更冗长

curl https://somewhere.com/somepath   \
--silent \
--insecure \
--request POST \
--header "your-curl-may-want-a-header" \
--data @my.input.file \
--output site.output \
--write-out %{http_code} \
  > http.response.code 2> error.messages
errorLevel=$?
httpResponse=$(cat http.response.code)


jq --raw-output 'keys | @csv' site.output | sed 's/"//g' > return.keys
hasErrors=`grep --quiet --invert errors return.keys;echo $?`

if [[ $errorLevel -gt 0 ]] || [[ $hasErrors -gt 0 ]] || [[ "$httpResponse" != "200" ]]; then
  echo -e "Error POSTing https://somewhere.com/somepath with input my.input (errorLevel $errorLevel, http response code $httpResponse)" >> error.messages
  send_exit_message # external function to send error.messages to whoever.
fi

这可以帮助评估 http 状态

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

另一种变体:

       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-)

我不喜欢这里将数据与状态混合在一起的答案。 发现这一点:您添加 -f 标志以使 curl 失败并从标准状态变量中获取错误状态代码:$?

https://unix.stackexchange.com/questions/204762/return-code-for-curl-used-in-a-command-substitution

我不知道它是否适合这里的每个场景,但它似乎符合我的需求,而且我认为它更容易使用

这是冗长但易于理解的脚本,其灵感来自于nicerobot的解决方案,它只请求响应标头并避免使用此处建议的 IFS。 它在遇到响应 >= 400 时输出一个弹跳消息。这个回声可以用一个弹跳脚本代替。

# 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) - 结果中的最后一行将是响应代码

然后,您可以使用类似以下内容从响应中解析响应代码,其中 X 可以表示正则表达式以标记响应的结束(此处使用 json 示例)

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

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

  1. 假设您已经为您的应用程序实现了停止和启动脚本。 创建一个脚本如下检查你的应用程序 url 的 http 状态并在 502 的情况下重新启动:

httpStatusCode=$(curl -s -o /dev/null -w "%{http_code}" https://{your_url}/) if [ $httpStatusCode = 502 ]; 然后 sh /{path_to_folder}/stopscript.sh sh /{path_to_folder}/startscript.sh fi

  1. 实现一个 cron 作业,每 5 分钟调用一次这个脚本。 假设上述脚本的名称为 checkBootAndRestart.sh。 然后你的 crontab 应该看起来像 - */5 * * * * /{path_to_folder}/checkBootAndRestart.sh

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM