बैश / शेल स्क्रिप्ट से http प्रतिक्रिया कोड का मूल्यांकन कैसे करें?


203

मुझे लगता है कि मैं स्पष्ट याद कर रहा हूँ, लेकिन सफल नहीं हुआ है के साथ man [curl|wget]या गूगल ("http" इस तरह के एक बुरा खोज शब्द बनाता है)। मैं हमारे एक वेबसर्वर को एक त्वरित और गंदे फिक्स की तलाश कर रहा हूं जो अक्सर विफल रहता है, त्रुटि संदेश के साथ स्थिति कोड 500 लौटाता है। एक बार ऐसा होने पर, इसे पुनः आरंभ करने की आवश्यकता है।

जैसा कि मूल कारण खोजने में कठिन लगता है, हम एक त्वरित तय करने के लिए लक्ष्य बना रहे हैं, उम्मीद करते हैं कि यह समय को पाटने के लिए पर्याप्त होगा जब तक कि हम इसे ठीक नहीं कर सकते (सेवा को उच्च उपलब्धता की आवश्यकता नहीं है)

प्रस्तावित समाधान क्रोन जॉब बनाना है जो हर 5 मिनट में http: // localhost: 8080 / की जाँच करता है । यदि यह स्थिति कोड 500 के साथ लौटती है, तो वेबसर्वर को फिर से शुरू किया जाएगा। सर्वर एक मिनट के भीतर फिर से चालू हो जाएगा, इसलिए पहले से चल रहे पुनरारंभ की जांच करने की कोई आवश्यकता नहीं है।

विचाराधीन सर्वर एक ubuntu 8.04 न्यूनतम स्थापना है, जो कि वर्तमान में इसकी जरूरत है, इसे चलाने के लिए पर्याप्त पैकेज स्थापित किया गया है। कार्य को करने के लिए कोई कठिन आवश्यकता नहीं है, लेकिन मैं चाहूंगा कि किसी भी अधिक व्याख्याताओं को स्थापित किए बिना इस तरह के न्यूनतम वातावरण में चला जाए।

(मैं स्क्रिप्टिंग के साथ पर्याप्त रूप से परिचित हूं कि कमांड / विकल्प एक पर्यावरण चर के लिए http स्थिति कोड असाइन करने के लिए पर्याप्त होगा - यह वही है जो मैंने देखा है और नहीं मिल सकता है।)

जवाबों:


316

मैंने 500 कोड पर इसका परीक्षण नहीं किया है, लेकिन यह 200, 302 और 404 जैसे अन्य पर काम करता है।

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

ध्यान दें, - राइट-आउट के लिए प्रदान किया गया प्रारूप उद्धृत किया जाना चाहिए। जैसा कि @ibai द्वारा सुझाया गया है, --headकेवल एक अनुरोध बनाने के लिए जोड़ें । यह उस समय की बचत करेगा जब पृष्ठ सामग्री प्रसारित नहीं होने के बाद पुनर्प्राप्ति सफल होगी।


1
अच्छा - धन्यवाद: मैंने पहले ही लिख दिया है - राइट-आउट, लेकिन - the -putput / dev / null से चूक गया। जब सभी सामग्री इसके साथ आती है, तो प्रतिक्रिया कोड बहुत अधिक जानकारी में खो जाता है, इसलिए मैंने बस इसे नहीं देखा ...
ओलाफ कोक

4
क्या मैं प्रतिक्रिया कोड और आउटपुट दोनों को अलग-अलग चर में स्टोर कर सकता हूं? मैं आउटपुट को प्रतिध्वनित करना चाहूंगा जब प्रतिक्रिया कोड 200 नहीं है
वैभव बाजपेयी

7
@VaibhavBajpai: इसका प्रयास करें: response=$(curl --write-out \\n%{http_code} --silent --output - servername)- परिणाम में अंतिम पंक्ति प्रतिक्रिया कोड होगी।
अगली सूचना तक रोक दिया गया।

2
यदि अंतिम अनुरोध का परिणाम 3XX है, तो यह अंतिम अनुरोध स्थिति नहीं दिखाता है। उदाहरण के लिए यदि लौटाया गया मान 301 रीडायरेक्ट है, तो यह स्क्रिप्ट वहीं रुक जाती है। यदि आप -IL जोड़ते हैं, तो आप अंतिम स्थिति प्राप्त कर सकते हैं। यदि आप सभी अनुरोधों के लिए सभी HTTP स्टेटस दिखाना चाहते हैं, तो नीचे दिए गए मेरे उदाहरण का उपयोग करें।
सिलिकॉनक्रॉस्टर

महान काम, धन्यवाद! हालांकि मेरे मामले में (https) मुझे भी डालने की जरूरत थी --insecure
टॉमाज़ राशिया

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

काम करता है। यदि नहीं, तो आपको कोड को देखने के लिए ही रिटर्न मारना होगा।


33

मुझे आज जल्दी से कुछ प्रदर्शित करने की आवश्यकता थी और इसके साथ आया। सोचा था कि मैं इसे यहां रखूंगा अगर किसी को ओपी के अनुरोध के समान कुछ चाहिए।

#!/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 से हर राज्य परिवर्तन पर एक ईमेल अलर्ट भेजेगा, इसलिए यह गूंगा और संभावित लालची है। इसे सुधारने के लिए, मैं कई स्टेटस कोड्स के माध्यम से लूपिंग करूँगा और परिणाम पर निर्भर विभिन्न क्रियाओं को करूँगा।


20

यद्यपि स्वीकृत प्रतिक्रिया एक अच्छा उत्तर है, लेकिन यह विफलता परिदृश्यों की अनदेखी करती है। यदि अनुरोध में कोई त्रुटि है या कनेक्शन विफलता है, तो 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

9

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

सभी अनुरोधों के लिए 3XX पुनर्निर्देशन और प्रिंट प्रतिक्रिया कोड का पालन करें:

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

grepउन में "HTTP" के साथ सभी लाइनों पर कब्जा होगा। हो सकता है grep -m 1 HTTPकि केवल पहले मैच को ही हड़प लें, अगर वह इरादा है, या शायद इसके बजाय पाइप को Awk करने के लिए बस परिणाम कोड को पार्स करें।
ट्रिपल जू

3

यह http स्थिति का मूल्यांकन करने में मदद कर सकता है

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

2
head -n 1 | awk '{stuff}' एक एंटीपार्टन का एक सा है, awk 'NR==1 {stuff}'एक प्रक्रिया में एक ही काम करता है, शुद्ध अवाक।
ट्रिपल

3

एक और भिन्नता:

       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

यहाँ लंबे समय से घुमावदार - अभी तक समझने में आसान है - स्क्रिप्ट, जो कि निस्सोरोबोट के समाधान से प्रेरित है , जो केवल प्रतिक्रिया हेडर का अनुरोध करता है और आईएफएस का उपयोग करने से बचता है जैसा कि यहाँ सुझाया गया है । जब यह एक प्रतिक्रिया> = 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

मुझे यहाँ ऐसे उत्तर पसंद नहीं हैं जो डेटा को स्टेटस के साथ मिलाते हैं। यह पाया: आप -f ध्वज को जोड़ने के लिए कर्ल विफल हो जाते हैं और मानक स्थिति संस्करण से त्रुटि स्थिति कोड उठाते हैं: $?

/unix/204762/return-code-for-curl-used-in-a-command-substitution

मुझे नहीं पता कि यह यहां के हर परिदृश्य के लिए एकदम सही है, लेकिन यह मेरी जरूरतों को पूरा करता है और मुझे लगता है कि इसके साथ काम करना बहुत आसान है


1

यहां मेरा कार्यान्वयन है, जो पिछले कुछ उत्तरों की तुलना में थोड़ा अधिक क्रियात्मक है

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

0

ऊपर @DennisWilliamson टिप्पणी जोड़ने के लिए:

@VahavhavBajpai: इसका प्रयास करें: प्रतिक्रिया = $ (कर्ल - राइट-आउट \ n% {http_code} --silent --output - servername) - परिणाम में अंतिम पंक्ति प्रतिक्रिया कोड होगी

फिर आप निम्न जैसे कुछ का उपयोग करके प्रतिक्रिया से प्रतिक्रिया कोड को पार्स कर सकते हैं, जहां एक्स प्रतिक्रिया के अंत को चिह्नित करने के लिए एक regex को इंगित कर सकता है (यहां एक json उदाहरण का उपयोग करके)

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

पदार्थ निकालना देखें: http://tldp.org/LDP/abs/html/string-manipulation.html


आप एक चर में पैटर्न क्यों डालेंगे, और आप अंतिम मूल्य प्राप्त करने के लिए बेकारecho का उपयोग क्यों करेंगे ? बस code=${response##*\}}सरल है और कई आम नुकसान से बचा जाता है। इसके अलावा, यह एक ग्लोब पैटर्न है, एक उचित नियमित अभिव्यक्ति नहीं है।
ट्रिपल जू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.