私のサーバーを継続的にテストし、サーバーがダウンしたら、私に電子メールを送信するためにここにシェルスクリプトを作成しようとしています。
問題は、ssh接続からログアウトしたとき&
にコマンドの最後に実行したにもかかわらず、./stest01.sh &
自動的にelseに落ち、再度ログインして終了するまでメールを送信し続けることです。
#!/bin/bash
while true; do
date > sdown.txt ;
cp /dev/null pingop.txt ;
ping -i 1 -c 1 -W 1 myserver.net > pingop.txt &
sleep 1 ;
if
grep "64 bytes" pingop.txt ;
then
:
else
mutt -s "Server Down!" [email protected] < sdown.txt ;
sleep 10 ;
fi
done
答え1
grep
GNUが結果を書き込もうとすると、SSH接続が失われ、出力を書き込む場所がないため、ゼロ以外の終了状態で失敗します。
これはif
ステートメントが常にelse
分岐を取ることを意味します。
これを説明するために(これではありません。正確に現在の状況は次のとおりです。ただし、grep
GNUが出力を作成できない場合に何が起こるかを示します。
$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2
ここにgrep
生成された文字列がありますが、どこにも書き込めないように両方のecho
出力ストリームを閉じます。grep
ご覧のとおり、GNUの終了状態はgrep
0ではなく2です。
これはGNUに固有のもので、grep
BSDgrep
システムでは同じようには機能しません。
$ 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!" [email protected] <sdown.txt
break
fi
sleep 10
done
また、中間ファイルの1つを必要とせずにテストを直接使用することもできますping
(実際には日付スタンプのみを含む他の中間ファイルも削除されます)。
#!/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!" [email protected]
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!" [email protected]
1分ごとに実行されるクローン操作(サーバーが停止し続けると、電子メールは1分ごとに送信され続けます):
* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" [email protected] )