I am trying to write a bash script in a file that would, when run start pinging a host until it becomes available, when the host becomes reachable it runs a command and stops executing, I tried writing one but the script continues pinging until the count ends,
Plus I need to put that process in the background but if I run the script with the dollar (
$) sign it still runs in foreground,
#!/bin/bash ping -c30 -i3 192.168.137.163 if [ $? -eq 0 ] then /root/scripts/test1.sh exit 0 else echo “fail” fi
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
I would use this, a simple one-liner:
while ! ping -c1 HOSTNAME &>/dev/null; do echo "Ping Fail - `date`"; done ; echo "Host Found - `date`" ; /root/scripts/test1.sh
HOSTNAMEwith the host you are trying to ping.
I missed the part about putting it in the background, put that line in a shellscript like so:
#!/bin/sh while ! ping -c1 $1 &>/dev/null do echo "Ping Fail - `date`" done echo "Host Found - `date`" /root/scripts/test1.sh
And to background it you would run it like so:
nohup ./networktest.sh HOSTNAME > /tmp/networktest.out 2>&1 &
HOSTNAMEwith the host you are trying to ping. In this approach you are passing the hostname as an argument to the shellscript.
Just as a general warning, if your host stays down, you will have this script continuously pinging in the background until you either kill it or the host is found. So I would keep that in mind when you run this. Because you could end up eating system resources if you forget about this.
By passing the parameters ‘-c 30’ to ping, it will try 30 ping and stop. It will check after if the command succeeds. I think it is best to do a loop that contains one ping and check if this ping succeed. Something like that:
while true; do ping -c1 google.com if [ $? -eq 0 ] then /root/scripts/test1.sh exit 0 fi done
If by still running on the foreground, you mean it is still printing on the terminal, you can redirect stdin and stdout to /dev/null .
ping -oc 100000 Hostname > /dev/null && /root/scripts/test1.sh
ping -oexits the
pingafter the first packet is received
> /dev/nullredirects the output, so you won’t see it
&&would run the next command, if the previous command ere successful
In addition, you can run any process in the background by adding
& to the end of it; for example,
echo "123" & will run in the background
An old post, but as a suggestion you can use the
-w option on ping to avoid the loop. For example,
ping -w 30 -c 1 host
will try for 30 seconds with one ping per second (default ping has 1 second interval between pings) and will exit on the first successful ping.
If you don’t need a timeout, I.e. wait for ever, just use a very large value with
Here is working modification of your script.
#!/bin/bash ping -c1 10.1.1.23 > /dev/null if [ $? -eq 0 ] then echo ok exit 0 else echo “fail” fi
You need to send the output to
/dev/nullso it won’t appear on the screen.
-c is meant for count. If you put
-c30, you’re going to ping 30 times before your script can move on to the next line. I use
-c1 to make the script run faster.
-i is to wait seconds between sending each packet. So
-i3 is to wait 3 seconds. I remove
-i to make the script run faster.
Last but not least, use indention so that your code looks nice and easier to read.
<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="641117011624080d0a111c">[email protected]</a>:~$ ./script.sh ok <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="91e4e2f4e3d1fdf8ffe4e9">[email protected]</a>:~$ <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7d080e180f3d1114130805">[email protected]</a>:~$ ./script.sh “fail” <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7e0b0d1b0c3e1217100b06">[email protected]</a>:~$
#!/bin/sh if [ $1 ] then for i in ` cat $1` do VAR1=$(ping -ac 2 $i| grep -c error) if [ $VAR1 == "0" ] then echo " valid : $i" else echo " invalid : $i" fi done else echo " please present the file name. example: pong /tmp/a " fi