How to evaluate http response codes from bash/shel

2019-01-16 01:40发布

I have the feeling that I'm missing the obvious, but have not succeeded with man [curl|wget] or google ("http" makes such a bad search term). I'm looking for a quick&dirty fix to one of our webservers that frequently fails, returning status code 500 with an error message. Once this happens, it needs to be restarted.

As the root cause seems to be hard to find, we're aiming for a quick fix, hoping that it will be enough to bridge the time until we can really fix it (the service doesn't need high availability)

The proposed solution is to create a cron job that runs every 5 minutes, checking http://localhost:8080/. If this returns with status code 500, the webserver will be restarted. The server will restart in under a minute, so there's no need to check for restarts already running.

The server in question is a ubuntu 8.04 minimal installation with just enough packages installed to run what it currently needs. There is no hard requirement to do the task in bash, but I'd like it to run in such a minimal environment without installing any more interpreters.

(I'm sufficiently familiar with scripting that the command/options to assign the http status code to an environment variable would be enough - this is what I've looked for and could not find.)

10条回答
一纸荒年 Trace。
2楼-- · 2019-01-16 02:20
curl --write-out "%{http_code}\n" --silent --output /dev/null "$URL"

works. If not, you have to hit return to view the code itself.

查看更多
干净又极端
3楼-- · 2019-01-16 02:20

With netcat and awk you can handle the server response manually:

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
查看更多
倾城 Initia
4楼-- · 2019-01-16 02:21

I needed to demo something quickly today and came up with this. Thought I would place it here if someone needed something similar to the OP's request.

#!/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

This will send an email alert on every state change from 200, so it's dumb and potentially greedy. To improve this, I would look at looping through several status codes and performing different actions dependant on the result.

查看更多
孤傲高冷的网名
5楼-- · 2019-01-16 02:23

I haven't tested this on a 500 code, but it works on others like 200, 302 and 404.

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

As suggested by @ibai, add --head to make a HEAD only request. This will save time when the retrieval is successful since the page contents won't be transmitted.

查看更多
在下西门庆
6楼-- · 2019-01-16 02:29

Another variation:

status=$(curl -I https://www.healthdata.gov/user/login 2> /dev/null | head -n 1 | cut -d ' ' -f 2)
查看更多
手持菜刀,她持情操
7楼-- · 2019-01-16 02:31

To follow 3XX redirects and print response codes for all requests:

HTTP_STATUS="$(curl -IL --silent example.com | grep HTTP )";    
echo "${HTTP_STATUS}";
查看更多
登录 后发表回答