簡體   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