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;
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
|
show 2 more comments
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
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 beforeelse
.
– 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
|
show 2 more comments
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
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
linux shell-script grep ping bourne-shell
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 beforeelse
.
– 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
|
show 2 more comments
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 beforeelse
.
– 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
|
show 2 more comments
1 Answer
1
active
oldest
votes
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 )
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 addingexec </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
add a comment
|
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 )
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 addingexec </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
add a comment
|
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 )
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 addingexec </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
add a comment
|
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 )
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 )
edited Aug 12 at 15:24
answered Aug 11 at 12:41
Kusalananda♦Kusalananda
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 addingexec </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
add a comment
|
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 addingexec </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
add a comment
|
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 beforeelse
.– 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