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

Any help would be appreciated tnx in advance!

up vote 8 down vote accepted

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

Replace HOSTNAME with 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 &

Again replace HOSTNAME with 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.

  • Tnx for the answer and the warning, this is a visualized environment so the script will start after the physical servers boot so the VM's will start certainly, but will keep in mind if i delete a VM, tnx again – dusan90 Feb 12 '15 at 9:18
  • In particular by logging the failures every time, and storing all the output in a file in /tmp, if the host goes down you'll end up filling /tmp. That tends to be bad news... – Stephen Kitt Feb 13 '15 at 16:57

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 . Hope it helps

  • By unlocking the prompt so i could work on something else, tnx for help – dusan90 Feb 12 '15 at 9:17
ping -oc 100000 Hostname > /dev/null && /root/scripts/test1.sh 
  • ping -o exits the ping after the first packet is received
  • > /dev/null redirects 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 -w.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.