Skip to main content
3 of 9
added 240 characters in body
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k

When GNU grep tries to write its result, it will fail with a non-zero exit status, because it has nowhere to write the output, because the SSH connection is gone.

This means that the if statement is always taking the else branch.

To illustrate this:

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

Here we grep for the string that echo produces, but we close both output streams for grep so that it can't write anywhere. As you can see, the exit status of GNU grep is 2 rather than 0.

This is particular to GNU grep and BSD grep won't behave the same:

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

To remedy this, don't force grep to output the lines that matches the pattern. You do this with the -q option.

In short:

#!/bin/bash

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

You may also use a test on ping directly, removing the need for one of the intermediate files (and also getting rid of the other intermediate file that really only ever contains a datestamp):

#!/bin/bash

while true; do
    if ! ping -q -c 1 -W 1 myserver.net
        date | mutt -s "Server Down!" [email protected]
        break
    fi

    sleep 10
done

In both variations of the script above, I choose to exit the loop upon failure to reach the host, just to minimise the number of emails sent. You could instead replace the break with e.g. sleep 10m or something if you expect the server to eventually come up again.

I've also slightly tweaked the options used with ping as -i 1 does not make much sense with -c 1.

Shorter (unless you want it to continue sending emails when the host is unreachable):

#!/bin/bash

while ping -q -c 1 -W 1 myserver.net; do
    sleep 10
done

date | mutt -s "Server Down!" [email protected]
Kusalananda
  • 355.8k
  • 42
  • 735
  • 1.1k