Khi GNU grep
cố gắng ghi kết quả của nó, nó sẽ thất bại với trạng thái thoát khác không, bởi vì nó không có nơi nào để ghi đầu ra, vì kết nối SSH đã biến mất.
Điều này có nghĩa là if
tuyên bố luôn lấy else
chi nhánh.
Để minh họa điều này (đây không chính xác là những gì xảy ra trong trường hợp của bạn, nhưng nó cho thấy điều gì xảy ra nếu GNU grep
không thể ghi đầu ra của nó):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Ở đây chúng tôi grep
cho chuỗi echo
tạo ra, nhưng chúng tôi đóng cả hai luồng đầu ra grep
để nó không thể ghi ở bất cứ đâu. Như bạn có thể thấy, trạng thái thoát của GNU grep
là 2 chứ không phải 0.
Điều này đặc biệt đối với GNU grep
, grep
trên các hệ thống BSD sẽ không hoạt động giống nhau:
$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0
Để khắc phục điều này, hãy đảm bảo rằng tập lệnh không tạo đầu ra. Bạn có thể làm điều này với exec >/dev/null 2>&1
. Ngoài ra, chúng ta nên sử dụng grep
với -q
tùy chọn của nó vì chúng ta hoàn toàn không thích nhìn thấy đầu ra từ nó (điều này thường cũng sẽ tăng tốc grep
vì không cần phải phân tích toàn bộ tệp, nhưng trong trường hợp này, nó làm rất ít sự khác biệt về tốc độ vì tập tin quá nhỏ).
Nói ngắn gọn:
#!/bin/sh
# redirect all output not redirected elsewhere to /dev/null by default:
exec >/dev/null 2>&1
while true; do
date >sdown.txt
ping -c 1 -W 1 myserver.net >pingop.txt
if ! grep -q "64 bytes" pingop.txt; then
mutt -s "Server Down!" myemail@address.com <sdown.txt
break
fi
sleep 10
done
Bạn cũng có thể sử dụng thử nghiệm ping
trực tiếp, loại bỏ sự cần thiết của một trong các tệp trung gian (và cũng loại bỏ tệp trung gian khác thực sự chỉ chứa một dấu thời gian):
#!/bin/sh
exec >/dev/null 2>&1
while true; do
if ! ping -q -c 1 -W 1 myserver.net; then
date | mutt -s "Server Down!" myemail@address.com
break
fi
sleep 10
done
Trong cả hai biến thể của tập lệnh ở trên, tôi chọn thoát khỏi vòng lặp khi không đến được máy chủ, chỉ để giảm thiểu số lượng email được gửi. Thay vào đó, bạn có thể thay thế break
bằng ví dụ sleep 10m
hoặc một cái gì đó nếu bạn mong muốn máy chủ sẽ xuất hiện trở lại.
Tôi cũng đã điều chỉnh một chút các tùy chọn được sử dụng ping
vì -i 1
không có nhiều ý nghĩa với -c 1
.
Ngắn hơn (trừ khi bạn muốn nó tiếp tục gửi email khi máy chủ không thể truy cập được):
#!/bin/sh
exec >/dev/null 2>&1
while ping -q -c 1 -W 1 myserver.net; do
sleep 10
done
date | mutt -s "Server Down!" myemail@address.com
Là một công việc định kỳ chạy mỗi phút (sẽ tiếp tục gửi email mỗi phút nếu máy chủ tiếp tục ngừng hoạt động):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )
:
làm gì? Nó có ý nghĩa với tôi nó là một dấu chấm phẩy;
...