2010-02-08 25 views
123

Tôi có cảm giác rằng tôi đang thiếu hiển nhiên, nhưng chưa thành công với man [curl|wget] hoặc google ("http" làm cho cụm từ tìm kiếm xấu đó). Tôi đang tìm kiếm một sửa lỗi bẩn & nhanh chóng đến một trong các máy chủ web của chúng tôi thường xuyên bị lỗi, trả lại mã trạng thái 500 bằng thông báo lỗi. Khi điều này xảy ra, nó cần phải được khởi động lại.Cách đánh giá mã phản hồi http từ tập lệnh bash/shell?

Vì nguyên nhân gốc rễ có vẻ khó tìm, chúng tôi đang cố gắng sửa chữa nhanh chóng, hy vọng rằng sẽ đủ để kết nối thời gian cho đến khi chúng tôi thực sự khắc phục được (dịch vụ không cần tính sẵn sàng cao)

Giải pháp được đề xuất là tạo một công việc cron chạy cứ sau 5 phút, kiểm tra http://localhost:8080/. Nếu điều này trả về với mã trạng thái 500, máy chủ web sẽ được khởi động lại. Máy chủ sẽ khởi động lại sau một phút, do đó, không cần phải kiểm tra xem đã khởi động lại chưa.

Máy chủ được đề cập là bản cài đặt tối thiểu ubuntu 8.04 với chỉ đủ gói được cài đặt để chạy những gì nó hiện đang cần. Không có yêu cầu khó khăn để làm nhiệm vụ trong bash, nhưng tôi muốn nó chạy trong môi trường tối thiểu như vậy mà không cần cài đặt thêm bất kỳ phiên dịch nào.

(Tôi đủ quen thuộc với kịch bản lệnh/tùy chọn để gán mã trạng thái http đến một biến môi trường sẽ là đủ - đây là những gì tôi đã nhìn cho và không thể tìm thấy.)

Trả lời

208

tôi chưa được thử nghiệm này trên một mã số 500, nhưng nó hoạt động trên những người khác như 200, 302 và 404.

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

Tốt - cảm ơn: Tôi đã tìm thấy - ghi-ra, nhưng đã bỏ lỡ --output/dev/null. Khi tất cả nội dung đi kèm với nó, mã phản hồi bị mất trong quá nhiều thông tin, vì vậy tôi chỉ đơn giản là không nhìn thấy nó ... –

+3

Tôi có thể lưu trữ cả mã phản hồi và đầu ra trong các biến riêng biệt không? Tôi muốn echo đầu ra khi mã phản hồi không phải là 200 –

+5

@VaibhavBajpai: Hãy thử điều này: 'response = $ (curl - ghi-ra \\ n% {http_code} --silent --output - servername)' - dòng cuối cùng trong kết quả sẽ là mã phản hồi. –

8

với netcat và awk bạn có thể xử lý các phản ứng máy chủ bằng tay:

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 
+1

Rất tốt - cảm ơn rất nhiều –

+3

Đây là nội dung hardcore – alonisser

13

đây:

url='http://localhost:8080/' 
status=$(r=(IFS=' ';$(curl -Is --connect-timeout 5 "${url}" || echo 1 500));echo ${r[1]}) 
[ status -eq 500 ] && bounce # assuming the bounce script is called 'bounce' 

Hoặc đặt nó trên cùng một dòng:

[ 500 -eq $(r=(IFS=' ';$(curl -Is --connect-timeout 5 'http://localhost:8080/' || echo 1 500));echo ${r[1]}) ] && bounce 

Để giải thích, phản ứng HTTP luôn chứa tình trạng máy chủ như là một phần của dòng đầu tiên của câu trả lời, như:

HTTP/1.1 200 OK 
HTTP/1.0 404 NOT FOUND 

Tập lệnh chỉ sử dụng curl để thực hiện yêu cầu HEAD tới localhost: 8080. Nó chuyển đổi tiêu đề HTTP thành mảng và trả về phần tử thứ hai. Để đơn giản hóa một số lỗi xử lý, nếu HEAD không kết nối trong vòng 5 giây hoặc curl không thành công vì lý do nào đó, 500 cũng được trả lại.

+0

Cảm ơn bạn rất nhiều. –

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

hoạt động. Nếu không, bạn phải nhấn trở lại để xem mã chính nó.

7

Để thực hiện theo 3XX chuyển hướng và mã phản ứng in cho tất cả các yêu cầu:

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

'grep' sẽ ghi lại tất cả các dòng có" HTTP "trong chúng. Có thể 'grep -m 1 HTTP' để chỉ lấy kết quả đầu tiên, nếu đó là mục đích, hoặc có thể thay vào đó để chuyển sang Awk để phân tích cú pháp chỉ là mã kết quả. – tripleee

1

này có thể giúp để đánh giá tình trạng http

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

'head -n 1 | awk '{stuff}' 'là một chút của một antipattern, 'awk' NR == 1 {stuff} '' làm điều tương tự trong một quá trình, Awk tinh khiết. – tripleee

0

Để thêm vào @DennisWilliamson bình luận trên:

@VaibhavBajpai: Hãy thử điều này: response = $ (curl --write-out \ n% {http_code} --silent --output - servername) - dòng cuối cùng trong res ult sẽ là mã phản hồi

Sau đó bạn có thể phân tích các mã phản hồi từ các phản ứng sử dụng một cái gì đó như sau, trong đó X có thể biểu hiện một regex để đánh dấu sự kết thúc của phản ứng (sử dụng một ví dụ json đây)

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

Xem xâu Removal: http://tldp.org/LDP/abs/html/string-manipulation.html

+0

Tại sao bạn sẽ đặt mẫu trong một biến, và tại sao bạn sẽ sử dụng một [echo' vô dụng] (http://www.iki.fi/era/unix/award.html # echo) để có được giá trị cuối cùng? Chỉ cần 'code = $ {response ## * \}}' đơn giản hơn và tránh được một số cạm bẫy phổ biến. Ngoài ra, đó là một mô hình glob, không phải là một biểu thức chính quy thích hợp. – tripleee

1

Một biến thể:

status=$(curl -I https://www.healthdata.gov/user/login 2> /dev/null | head -n 1 | cut -d ' ' -f 2) 
1

Ở đây có đoạn mã dài - nhưng dễ hiểu - được lấy cảm hứng từ giải pháp nicerobot, chỉ yêu cầu tiêu đề phản hồi và tránh sử dụng IFS như đề xuất here. Nó xuất ra một tin nhắn bị trả lại khi nó gặp phản hồi> = 400. Có thể thay thế echo này bằng một tập lệnh bị trả về.

# 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

Tôi cần phải giới thiệu điều gì đó nhanh chóng hôm nay và đã đưa ra điều này. Nghĩ rằng tôi sẽ đặt nó ở đây nếu ai đó cần một cái gì đó tương tự như yêu cầu của 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 

Điều này sẽ gửi cảnh báo qua email về mọi thay đổi trạng thái từ 200, do đó, nó rất câm và có khả năng tham lam. Để cải thiện điều này, tôi sẽ xem xét lặp qua một số mã trạng thái và thực hiện các hành động khác nhau phụ thuộc vào kết quả.

Các vấn đề liên quan