Ketika GNU grepmencoba 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 ifpernyataan itu selalu mengambil elsecabang.
Untuk menggambarkan hal ini (ini bukan persis apa yang terjadi dalam kasus Anda, tapi itu menunjukkan apa yang terjadi jika GNU greptidak dapat menulis output):
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
Di sini kita grepmencari string yang echomenghasilkan, tetapi kita menutup kedua aliran keluaran grepagar tidak dapat menulis di mana pun. Seperti yang Anda lihat, status keluar dari GNU grepadalah 2 daripada 0.
Ini khusus untuk GNU grep, greppada 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 grepdengan -qopsi ini karena kita sama sekali tidak tertarik melihat output dari itu (ini umumnya juga akan mempercepat grepkarena 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 pinglangsung, 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 breakdengan eg sleep 10matau sesuatu jika Anda mengharapkan server akhirnya muncul lagi.
Saya juga sedikit mengubah opsi yang digunakan pingsebagai-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;...