Ketika GNU grep
mencoba untuk menulis hasilnya, ia akan gagal dengan status keluar yang tidak nol, karena ia tidak punya tempat untuk menulis output, karena koneksi SSH hilang.
Ini berarti bahwa if
pernyataan itu selalu mengambil else
cabang.
Untuk menggambarkan hal ini (ini bukan persis apa yang terjadi dalam kasus Anda, tapi itu menunjukkan apa yang terjadi jika GNU grep
tidak dapat menulis output):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Di sini kita grep
mencari string yang echo
menghasilkan, tetapi kita menutup kedua aliran keluaran grep
agar tidak dapat menulis di mana pun. Seperti yang Anda lihat, status keluar dari GNU grep
adalah 2 daripada 0.
Ini khusus untuk GNU grep
, grep
pada sistem BSD tidak akan berlaku sama:
$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0
Untuk memperbaiki ini, pastikan skrip tidak menghasilkan output. Anda dapat melakukannya dengan exec >/dev/null 2>&1
. Juga, kita harus menggunakan grep
dengan -q
opsi ini karena kita sama sekali tidak tertarik melihat output dari itu (ini umumnya juga akan mempercepat grep
karena tidak perlu menguraikan seluruh file, tetapi dalam hal ini membuat sangat sedikit perbedaan kecepatan karena file sangat kecil).
Pendeknya:
#!/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
Anda juga dapat menggunakan tes ping
langsung, menghapus kebutuhan untuk salah satu file perantara (dan juga menyingkirkan file perantara lainnya yang benar-benar hanya berisi 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
Dalam kedua variasi skrip di atas, saya memilih untuk keluar dari loop setelah gagal mencapai host, hanya untuk meminimalkan jumlah email yang dikirim. Anda bisa mengganti break
dengan eg sleep 10m
atau sesuatu jika Anda mengharapkan server akhirnya muncul lagi.
Saya juga sedikit mengubah opsi yang digunakan ping
sebagai-i 1
tidak masuk akal -c 1
.
Lebih pendek (kecuali jika Anda ingin terus mengirim email ketika tuan rumah tidak terjangkau):
#!/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
Sebagai pekerjaan cron yang berjalan setiap menit (akan terus mengirim email setiap menit jika server terus turun):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )
:
? Akan masuk akal bagi saya itu adalah titik koma;
...