web-dev-qa-db-ja.com

bash / Shellスクリプトからのhttp応答コードを評価する方法は?

私は明らかなことを見逃していると感じていますが、man [curl|wget]またはgoogleで成功していません(「http」はそのような悪い検索用語になります)。頻繁に失敗し、エラーメッセージ付きのステータスコード500を返す、Webサーバーの1つに対する迅速で不潔な修正を探しています。これが発生したら、再起動する必要があります。

根本的な原因を見つけるのが難しいように見えるので、私たちは本当に修正できるまでの時間を橋渡しするのに十分であることを望んで、迅速な修正を目指しています(サービスには高可用性は必要ありません)

提案された解決策は、 http:// localhost:8080 / を確認して、5分ごとに実行されるcronジョブを作成することです。これがステータスコード500で返された場合、Webサーバーは再起動されます。サーバーは1分以内に再起動するため、既に実行されている再起動を確認する必要はありません。

問題のサーバーは、ubuntu 8.04の最小インストールで、現在必要なものを実行するのに十分なパッケージがインストールされています。 bashでタスクを実行するのに厳しい要件はありませんが、インタープリターをインストールすることなく、このような最小限の環境で実行したいと思います。

(httpステータスコードを環境変数に割り当てるコマンド/オプションで十分であるため、スクリプトについて十分に精通しています。これは私が探したもので、見つけることができませんでした。)

167
Olaf Kock

500コードでこれをテストしたことはありませんが、200、302、404などの他のコードでは動作します。

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

@ibaiが示唆するように、--headを追加して、HEADのみのリクエストを作成します。これにより、ページのコンテンツが送信されないため、取得が成功した場合に時間を節約できます。

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

動作します。そうでない場合は、リターンを押してコード自体を表示する必要があります。

36
hd1

今日すぐに何かをデモする必要があり、これを思いつきました。誰かが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から変更されるたびに電子メールアラートが送信されるため、愚かで欲張りになる可能性があります。これを改善するために、いくつかのステータスコードをループ処理し、結果に応じて異なるアクションを実行することを検討します。

16
Chris Gillatt

accepted response は良い答えですが、失敗のシナリオを見落としています。 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
13
nicerobot

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
9
marco

3XXリダイレクトに従い、すべてのリクエストの応答コードを出力するには:

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

別のバリエーション:

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

これは、httpステータスの評価に役立ちます

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

nicerobot の解決策に触発された、長文でありながら理解しやすいスクリプトがあります。これは、応答ヘッダーのみを要求し、提案されているようにIFSの使用を回避します here 。 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"
1
Thomas Praxl

上記の@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

0
user1015492