Trying to write a shell script that keeps testing a server remotely, but it keeps falling in else statement when I logoutHow can I run a command which will survive terminal close?How to write conditional if statement in bash shell script?Script in C shell skipping over last else statement?Write a shell script that takes in a variable from the terminal? (~$ command variable)I'm trying to write a script to compare results from a code to my already established results for regression testingBash script variable with if else statement but with loopWhat am I doing wrong trying to write a bash script that returns the number of the next available port?Shell script terminates connection from server but leaves connection openBash Script errors when trying to grep -v -q in if statementScript runs command fine, but fails when trying to save output to variable

C: Can't pass '#' as command-line argument

"packing with a hard knot in the pit of his stomach" meaning

In an interview, is it self-defeating to say you use StackOverflow to find errors in code?

Why don't we shield existing CPUs from radiation instead of designing new ones?

What can be found in towers of Tower Bridge?

Area of diagonal-folded regular polygon

How to Insert a console.log for word under cursor in new line

How to deal with third parties in physical pentests?

When does "The Mandalorian" take place?

Phrase/Word-pair for a variant of master-slave relationship

Conflict between a religious belief that accounts for the existence of transgender people vs. one that doesn't

Is there a mechanic for a PC to learn the relative strength of an opponent, stat-wise?

Can I wire this light fixture set with the plate mounted directly to the stud?

Does Global Entry require agreeing to a higher standard of behavior?

Can a Tiefling be born from two human parents?

The quietest classical orchestra instrument to play at home

Why does Rome municipality seem to have a hard time maintaining the city?

Monoids of endomorphisms of nonisomorphic groups

What does buying a wish in Sega's Aladdin do?

Why does "Endgame​" have its particular time travel theory?

What is smallest addressable value in an octal number called?

Is there a bulletproof way to know a file has been successfully decrypted?

Caesar cipher implementation in c++

Crack hashed passwords using a known password



Trying to write a shell script that keeps testing a server remotely, but it keeps falling in else statement when I logout


How can I run a command which will survive terminal close?How to write conditional if statement in bash shell script?Script in C shell skipping over last else statement?Write a shell script that takes in a variable from the terminal? (~$ command variable)I'm trying to write a script to compare results from a code to my already established results for regression testingBash script variable with if else statement but with loopWhat am I doing wrong trying to write a bash script that returns the number of the next available port?Shell script terminates connection from server but leaves connection openBash Script errors when trying to grep -v -q in if statementScript runs command fine, but fails when trying to save output to variable






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









9

















Trying here to write a shell script that keeps testing my server and email me when it becomes down.



The problem is that when I logout from ssh connection, despite running it with & at the end of command, like ./stest01.sh &, it automatically falls into else and keeps mailing me uninterruptedly, until I log again and kill it.



#!/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!" myemail@address.com < sdown.txt ;
sleep 10 ;
fi
done









share|improve this question























  • 1





    I am not a bash expert, but what does the colon : do? It would make sense to me it it were a semicolon ;...

    – Ned64
    Aug 11 at 12:21






  • 3





    @Ned64 The : does nothing. This is what it is designed to do. Here, instead of inverting the test, they use it to do a no-op before else.

    – Kusalananda
    Aug 11 at 12:22











  • @Kusalananda OK, thanks. Thought it might be a typo that could explain the problem.

    – Ned64
    Aug 11 at 12:24






  • 1





    I'm also confused why one would try to leave a shell script running after logout. Wouldn't cron or systemd timers be a better choice for this?

    – Cliff Armstrong
    Aug 11 at 13:26











  • Possible duplicate of How can I run a command which will survive terminal close?

    – Anthony G - justice for Monica
    Aug 12 at 16:27

















9

















Trying here to write a shell script that keeps testing my server and email me when it becomes down.



The problem is that when I logout from ssh connection, despite running it with & at the end of command, like ./stest01.sh &, it automatically falls into else and keeps mailing me uninterruptedly, until I log again and kill it.



#!/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!" myemail@address.com < sdown.txt ;
sleep 10 ;
fi
done









share|improve this question























  • 1





    I am not a bash expert, but what does the colon : do? It would make sense to me it it were a semicolon ;...

    – Ned64
    Aug 11 at 12:21






  • 3





    @Ned64 The : does nothing. This is what it is designed to do. Here, instead of inverting the test, they use it to do a no-op before else.

    – Kusalananda
    Aug 11 at 12:22











  • @Kusalananda OK, thanks. Thought it might be a typo that could explain the problem.

    – Ned64
    Aug 11 at 12:24






  • 1





    I'm also confused why one would try to leave a shell script running after logout. Wouldn't cron or systemd timers be a better choice for this?

    – Cliff Armstrong
    Aug 11 at 13:26











  • Possible duplicate of How can I run a command which will survive terminal close?

    – Anthony G - justice for Monica
    Aug 12 at 16:27













9












9








9


1






Trying here to write a shell script that keeps testing my server and email me when it becomes down.



The problem is that when I logout from ssh connection, despite running it with & at the end of command, like ./stest01.sh &, it automatically falls into else and keeps mailing me uninterruptedly, until I log again and kill it.



#!/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!" myemail@address.com < sdown.txt ;
sleep 10 ;
fi
done









share|improve this question

















Trying here to write a shell script that keeps testing my server and email me when it becomes down.



The problem is that when I logout from ssh connection, despite running it with & at the end of command, like ./stest01.sh &, it automatically falls into else and keeps mailing me uninterruptedly, until I log again and kill it.



#!/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!" myemail@address.com < sdown.txt ;
sleep 10 ;
fi
done






linux shell-script grep ping bourne-shell






share|improve this question
















share|improve this question













share|improve this question




share|improve this question








edited Oct 9 at 19:55







Vasconcelos1914

















asked Aug 11 at 12:09









Vasconcelos1914Vasconcelos1914

6664 silver badges23 bronze badges




6664 silver badges23 bronze badges










  • 1





    I am not a bash expert, but what does the colon : do? It would make sense to me it it were a semicolon ;...

    – Ned64
    Aug 11 at 12:21






  • 3





    @Ned64 The : does nothing. This is what it is designed to do. Here, instead of inverting the test, they use it to do a no-op before else.

    – Kusalananda
    Aug 11 at 12:22











  • @Kusalananda OK, thanks. Thought it might be a typo that could explain the problem.

    – Ned64
    Aug 11 at 12:24






  • 1





    I'm also confused why one would try to leave a shell script running after logout. Wouldn't cron or systemd timers be a better choice for this?

    – Cliff Armstrong
    Aug 11 at 13:26











  • Possible duplicate of How can I run a command which will survive terminal close?

    – Anthony G - justice for Monica
    Aug 12 at 16:27












  • 1





    I am not a bash expert, but what does the colon : do? It would make sense to me it it were a semicolon ;...

    – Ned64
    Aug 11 at 12:21






  • 3





    @Ned64 The : does nothing. This is what it is designed to do. Here, instead of inverting the test, they use it to do a no-op before else.

    – Kusalananda
    Aug 11 at 12:22











  • @Kusalananda OK, thanks. Thought it might be a typo that could explain the problem.

    – Ned64
    Aug 11 at 12:24






  • 1





    I'm also confused why one would try to leave a shell script running after logout. Wouldn't cron or systemd timers be a better choice for this?

    – Cliff Armstrong
    Aug 11 at 13:26











  • Possible duplicate of How can I run a command which will survive terminal close?

    – Anthony G - justice for Monica
    Aug 12 at 16:27







1




1





I am not a bash expert, but what does the colon : do? It would make sense to me it it were a semicolon ;...

– Ned64
Aug 11 at 12:21





I am not a bash expert, but what does the colon : do? It would make sense to me it it were a semicolon ;...

– Ned64
Aug 11 at 12:21




3




3





@Ned64 The : does nothing. This is what it is designed to do. Here, instead of inverting the test, they use it to do a no-op before else.

– Kusalananda
Aug 11 at 12:22





@Ned64 The : does nothing. This is what it is designed to do. Here, instead of inverting the test, they use it to do a no-op before else.

– Kusalananda
Aug 11 at 12:22













@Kusalananda OK, thanks. Thought it might be a typo that could explain the problem.

– Ned64
Aug 11 at 12:24





@Kusalananda OK, thanks. Thought it might be a typo that could explain the problem.

– Ned64
Aug 11 at 12:24




1




1





I'm also confused why one would try to leave a shell script running after logout. Wouldn't cron or systemd timers be a better choice for this?

– Cliff Armstrong
Aug 11 at 13:26





I'm also confused why one would try to leave a shell script running after logout. Wouldn't cron or systemd timers be a better choice for this?

– Cliff Armstrong
Aug 11 at 13:26













Possible duplicate of How can I run a command which will survive terminal close?

– Anthony G - justice for Monica
Aug 12 at 16:27





Possible duplicate of How can I run a command which will survive terminal close?

– Anthony G - justice for Monica
Aug 12 at 16:27










1 Answer
1






active

oldest

votes


















20


















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 (this is not exactly what's happening in your case, but it shows what happens if GNU grep is unable to write its output):



$ 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, grep on BSD systems won't behave the same:



$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0


To remedy this, make sure that the script does not generate output. You can do this with exec >/dev/null 2>&1. Also, we should be using grep with its -q option since we're not at all interested in seeing the output from it (this would generally also speed up the grep as it does not need to parse the whole file, but in this case it make very little difference in speed since the file is so small).



In short:



#!/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


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/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


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/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


As a cron job running every minute (would continue sending emails every minute if the server continues to be down):



* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )





share|improve this answer




























  • Using >&- will close the fd (as in, file descriptor 1 is closed), while closing the SSH connection will have a different effect (a file descriptor will be still around, but not connected to anything on the other side.) I think the point still stands, which is that GNU grep exits non-zero if it tries to write output and that fails. Yeah, best solution is just checking exit status of ping directly.

    – filbranden
    Aug 11 at 14:22






  • 4





    It might be safer to just redirect everything to/from /dev/null for the entire script by adding exec </dev/null >/dev/null 2>&1 near the beginning. That way if e.g. ping decides to write something to stderr it won't cause a problem.

    – Gordon Davisson
    Aug 11 at 19:35











  • @GordonDavisson I don't really see a reason to pull stdin from /dev/null here, but I sorted out the output. Thanks for the suggestion.

    – Kusalananda
    Aug 12 at 15:25













Your Answer








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);














draft saved

draft discarded
















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535001%2ftrying-to-write-a-shell-script-that-keeps-testing-a-server-remotely-but-it-keep%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown


























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









20


















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 (this is not exactly what's happening in your case, but it shows what happens if GNU grep is unable to write its output):



$ 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, grep on BSD systems won't behave the same:



$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0


To remedy this, make sure that the script does not generate output. You can do this with exec >/dev/null 2>&1. Also, we should be using grep with its -q option since we're not at all interested in seeing the output from it (this would generally also speed up the grep as it does not need to parse the whole file, but in this case it make very little difference in speed since the file is so small).



In short:



#!/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


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/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


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/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


As a cron job running every minute (would continue sending emails every minute if the server continues to be down):



* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )





share|improve this answer




























  • Using >&- will close the fd (as in, file descriptor 1 is closed), while closing the SSH connection will have a different effect (a file descriptor will be still around, but not connected to anything on the other side.) I think the point still stands, which is that GNU grep exits non-zero if it tries to write output and that fails. Yeah, best solution is just checking exit status of ping directly.

    – filbranden
    Aug 11 at 14:22






  • 4





    It might be safer to just redirect everything to/from /dev/null for the entire script by adding exec </dev/null >/dev/null 2>&1 near the beginning. That way if e.g. ping decides to write something to stderr it won't cause a problem.

    – Gordon Davisson
    Aug 11 at 19:35











  • @GordonDavisson I don't really see a reason to pull stdin from /dev/null here, but I sorted out the output. Thanks for the suggestion.

    – Kusalananda
    Aug 12 at 15:25
















20


















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 (this is not exactly what's happening in your case, but it shows what happens if GNU grep is unable to write its output):



$ 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, grep on BSD systems won't behave the same:



$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0


To remedy this, make sure that the script does not generate output. You can do this with exec >/dev/null 2>&1. Also, we should be using grep with its -q option since we're not at all interested in seeing the output from it (this would generally also speed up the grep as it does not need to parse the whole file, but in this case it make very little difference in speed since the file is so small).



In short:



#!/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


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/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


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/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


As a cron job running every minute (would continue sending emails every minute if the server continues to be down):



* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )





share|improve this answer




























  • Using >&- will close the fd (as in, file descriptor 1 is closed), while closing the SSH connection will have a different effect (a file descriptor will be still around, but not connected to anything on the other side.) I think the point still stands, which is that GNU grep exits non-zero if it tries to write output and that fails. Yeah, best solution is just checking exit status of ping directly.

    – filbranden
    Aug 11 at 14:22






  • 4





    It might be safer to just redirect everything to/from /dev/null for the entire script by adding exec </dev/null >/dev/null 2>&1 near the beginning. That way if e.g. ping decides to write something to stderr it won't cause a problem.

    – Gordon Davisson
    Aug 11 at 19:35











  • @GordonDavisson I don't really see a reason to pull stdin from /dev/null here, but I sorted out the output. Thanks for the suggestion.

    – Kusalananda
    Aug 12 at 15:25














20














20










20









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 (this is not exactly what's happening in your case, but it shows what happens if GNU grep is unable to write its output):



$ 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, grep on BSD systems won't behave the same:



$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0


To remedy this, make sure that the script does not generate output. You can do this with exec >/dev/null 2>&1. Also, we should be using grep with its -q option since we're not at all interested in seeing the output from it (this would generally also speed up the grep as it does not need to parse the whole file, but in this case it make very little difference in speed since the file is so small).



In short:



#!/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


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/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


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/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


As a cron job running every minute (would continue sending emails every minute if the server continues to be down):



* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )





share|improve this answer
















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 (this is not exactly what's happening in your case, but it shows what happens if GNU grep is unable to write its output):



$ 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, grep on BSD systems won't behave the same:



$ echo 'hello' | grep hello >&- 2>&- # using BSD grep here
$ echo $?
0


To remedy this, make sure that the script does not generate output. You can do this with exec >/dev/null 2>&1. Also, we should be using grep with its -q option since we're not at all interested in seeing the output from it (this would generally also speed up the grep as it does not need to parse the whole file, but in this case it make very little difference in speed since the file is so small).



In short:



#!/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


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/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


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/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


As a cron job running every minute (would continue sending emails every minute if the server continues to be down):



* * * * * ping -q -c 1 -W 1 >/dev/null 2>&1 || ( date | mail -s "Server down" myemail@address.com )






share|improve this answer















share|improve this answer




share|improve this answer








edited Aug 12 at 15:24

























answered Aug 11 at 12:41









KusalanandaKusalananda

172k20 gold badges330 silver badges535 bronze badges




172k20 gold badges330 silver badges535 bronze badges















  • Using >&- will close the fd (as in, file descriptor 1 is closed), while closing the SSH connection will have a different effect (a file descriptor will be still around, but not connected to anything on the other side.) I think the point still stands, which is that GNU grep exits non-zero if it tries to write output and that fails. Yeah, best solution is just checking exit status of ping directly.

    – filbranden
    Aug 11 at 14:22






  • 4





    It might be safer to just redirect everything to/from /dev/null for the entire script by adding exec </dev/null >/dev/null 2>&1 near the beginning. That way if e.g. ping decides to write something to stderr it won't cause a problem.

    – Gordon Davisson
    Aug 11 at 19:35











  • @GordonDavisson I don't really see a reason to pull stdin from /dev/null here, but I sorted out the output. Thanks for the suggestion.

    – Kusalananda
    Aug 12 at 15:25


















  • Using >&- will close the fd (as in, file descriptor 1 is closed), while closing the SSH connection will have a different effect (a file descriptor will be still around, but not connected to anything on the other side.) I think the point still stands, which is that GNU grep exits non-zero if it tries to write output and that fails. Yeah, best solution is just checking exit status of ping directly.

    – filbranden
    Aug 11 at 14:22






  • 4





    It might be safer to just redirect everything to/from /dev/null for the entire script by adding exec </dev/null >/dev/null 2>&1 near the beginning. That way if e.g. ping decides to write something to stderr it won't cause a problem.

    – Gordon Davisson
    Aug 11 at 19:35











  • @GordonDavisson I don't really see a reason to pull stdin from /dev/null here, but I sorted out the output. Thanks for the suggestion.

    – Kusalananda
    Aug 12 at 15:25

















Using >&- will close the fd (as in, file descriptor 1 is closed), while closing the SSH connection will have a different effect (a file descriptor will be still around, but not connected to anything on the other side.) I think the point still stands, which is that GNU grep exits non-zero if it tries to write output and that fails. Yeah, best solution is just checking exit status of ping directly.

– filbranden
Aug 11 at 14:22





Using >&- will close the fd (as in, file descriptor 1 is closed), while closing the SSH connection will have a different effect (a file descriptor will be still around, but not connected to anything on the other side.) I think the point still stands, which is that GNU grep exits non-zero if it tries to write output and that fails. Yeah, best solution is just checking exit status of ping directly.

– filbranden
Aug 11 at 14:22




4




4





It might be safer to just redirect everything to/from /dev/null for the entire script by adding exec </dev/null >/dev/null 2>&1 near the beginning. That way if e.g. ping decides to write something to stderr it won't cause a problem.

– Gordon Davisson
Aug 11 at 19:35





It might be safer to just redirect everything to/from /dev/null for the entire script by adding exec </dev/null >/dev/null 2>&1 near the beginning. That way if e.g. ping decides to write something to stderr it won't cause a problem.

– Gordon Davisson
Aug 11 at 19:35













@GordonDavisson I don't really see a reason to pull stdin from /dev/null here, but I sorted out the output. Thanks for the suggestion.

– Kusalananda
Aug 12 at 15:25






@GordonDavisson I don't really see a reason to pull stdin from /dev/null here, but I sorted out the output. Thanks for the suggestion.

– Kusalananda
Aug 12 at 15:25



















draft saved

draft discarded















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535001%2ftrying-to-write-a-shell-script-that-keeps-testing-a-server-remotely-but-it-keep%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown









Popular posts from this blog

Tamil (spriik) Luke uk diar | Nawigatjuun

Align equal signs while including text over equalitiesAMS align: left aligned text/math plus multicolumn alignmentMultiple alignmentsAligning equations in multiple placesNumbering and aligning an equation with multiple columnsHow to align one equation with another multline equationUsing \ in environments inside the begintabularxNumber equations and preserving alignment of equal signsHow can I align equations to the left and to the right?Double equation alignment problem within align enviromentAligned within align: Why are they right-aligned?

Training a classifier when some of the features are unknownWhy does Gradient Boosting regression predict negative values when there are no negative y-values in my training set?How to improve an existing (trained) classifier?What is effect when I set up some self defined predisctor variables?Why Matlab neural network classification returns decimal values on prediction dataset?Fitting and transforming text data in training, testing, and validation setsHow to quantify the performance of the classifier (multi-class SVM) using the test data?How do I control for some patients providing multiple samples in my training data?Training and Test setTraining a convolutional neural network for image denoising in MatlabShouldn't an autoencoder with #(neurons in hidden layer) = #(neurons in input layer) be “perfect”?