เมื่อ GNU grep
พยายามเขียนผลลัพธ์มันจะล้มเหลวด้วยสถานะการออกที่ไม่เป็นศูนย์เนื่องจากไม่มีการเขียนผลลัพธ์เนื่องจากการเชื่อมต่อ SSH หายไป
ซึ่งหมายความว่าif
คำสั่งนั้นรับelse
สาขาเสมอ
เพื่อแสดงนี้ (นี้ไม่ว่าสิ่งที่เกิดขึ้นในกรณีของคุณ แต่มันก็แสดงให้เห็นถึงสิ่งที่เกิดขึ้นถ้า GNU grep
ไม่สามารถที่จะเขียนออกของมัน):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
ที่นี่เราgrep
ใช้สตริงที่echo
สร้าง แต่เราปิดสตรีมเอาต์พุตทั้งสองเพื่อgrep
ให้ไม่สามารถเขียนได้ทุกที่ อย่างที่คุณเห็นสถานะทางออกของ GNU grep
คือ 2 มากกว่า 0
นี่คือโดยเฉพาะอย่างยิ่งที่จะ GNU grep
, grep
บนระบบ BSD จะไม่ทำตัวเหมือนเดิม:
$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0
เพื่อแก้ไขปัญหานี้ให้แน่ใจว่าสคริปต์ไม่ได้สร้างผลลัพธ์ exec >/dev/null 2>&1
คุณสามารถทำเช่นนี้กับ นอกจากนี้เราควรใช้grep
กับ-q
ตัวเลือกเนื่องจากเราไม่สนใจที่จะเห็นผลลัพธ์จากมัน (โดยทั่วไปจะเร่งความเร็วgrep
เนื่องจากไม่จำเป็นต้องแยกไฟล์ทั้งหมด แต่ในกรณีนี้มันทำให้น้อยมาก ความแตกต่างของความเร็วเนื่องจากไฟล์มีขนาดเล็กมาก)
ในระยะสั้น:
#!/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
คุณอาจใช้การทดสอบping
โดยตรงลบความจำเป็นสำหรับไฟล์ระดับกลางไฟล์ใดไฟล์หนึ่ง (และกำจัดไฟล์กลางอื่น ๆ ที่เคยมีไฟล์ datestamp อยู่ด้วย):
#!/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
ในทั้งสองรูปแบบของสคริปต์ด้านบนฉันเลือกที่จะออกจากลูปเมื่อล้มเหลวในการเข้าถึงโฮสต์เพียงเพื่อลดจำนวนอีเมลที่ส่ง คุณสามารถแทนที่break
ด้วยเช่นsleep 10m
หรือบางสิ่งบางอย่างหากคุณคาดว่าเซิร์ฟเวอร์จะเกิดขึ้นอีกครั้ง
ฉันยังเอ็นดูเล็กน้อยตัวเลือกที่ใช้กับping
เป็นไม่ได้ทำให้ความรู้สึกมากกับ-i 1
-c 1
ตัวย่อ (เว้นแต่คุณต้องการให้ส่งอีเมลต่อเมื่อโฮสต์ไม่สามารถเข้าถึงได้):
#!/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
ในฐานะงาน cron รันทุกนาที (จะส่งอีเมลต่อทุกนาทีหากเซิร์ฟเวอร์ยังคงทำงานต่อไป):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )
:
ทำอะไรได้บ้าง มันจะทำให้รู้สึกถึงฉันมันเป็นอัฒภาค;
...