リモートでサーバーを継続的にテストするためにシェルスクリプトを作成しようとしていますが、ログアウトすると常にelseステートメントで停止します。

リモートでサーバーを継続的にテストするためにシェルスクリプトを作成しようとしていますが、ログアウトすると常にelseステートメントで停止します。

私のサーバーを継続的にテストし、サーバーがダウンしたら、私に電子メールを送信するためにここにシェルスクリプトを作成しようとしています。

問題は、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

grepGNUが結果を書き込もうとすると、SSH接続が失われ、出力を書き込む場所がないため、ゼロ以外の終了状態で失敗します。

これはifステートメントが常にelse分岐を取ることを意味します。

これを説明するために(これではありません。正確に現在の状況は次のとおりです。ただし、grepGNUが出力を作成できない場合に何が起こるかを示します。

$ echo 'hello' | grep hello >&- 2>&-
$ echo $?
2

ここにgrep生成された文字列がありますが、どこにも書き込めないように両方のecho出力ストリームを閉じます。grepご覧のとおり、GNUの終了状態はgrep0ではなく2です。

これはGNUに固有のもので、grepBSDgrepシステムでは同じようには機能しません。

$ 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] )

おすすめ記事