When you are playing with terraform or any other provisioning software for a while, you will most likely run into an issue rather sooner than later, where you will have to wait for a host to reboot. Sleeping during your execution steps is one thing, but what if there was a better way?

There actually is and it is directly integrated into ping: https://linux.die.net/man/8/ping

ping -c

The -c option of ping

-c count
Stop after sending count ECHO_REQUEST packets. With deadline option, ping waits for count ECHO_REPLY packets, until the timeout expires.

great that means we can use

$ ping <target> -c 1

and be done with it? Right?

Well its not so easy because ping, as any other looping software, can be used to flood your target. Since some services will see this a Denial of Service attack, there is a great chance that you will be banned from pinging the server again, because the network provider decided your flooding the server.

Luckily there is another flag that we can make use of that will help us here:

ping -i

The -i option of ping stands for interval and here is what it does:

-i interval
Wait interval seconds between sending each packet. The default is to wait for one second between each packet normally, or not to wait in flood mode. Only super-user may set interval to values less 0.2 seconds.

Awesome! that means we can use it in combination of -c and stop the flooding of the server and only ping our target every five seconds:

$ ping <target> -c 1 -i 5

Nice.

But are we done yet?

ping -w

In theory yes, but what is if your target never does boot up or ping is disabled? Our script will simply wait for ever and never finish. Therefore we need to do something about this and luckily ping has us covered again:

-w deadline
Specify a timeout, in seconds, before ping exits regardless of how many packets have been sent or received. In this case ping does not stop after count packet are sent, it waits either for deadline expire or until count probes are answered or for some error notification from network.

which turn our command into:

$ ping <target> -c 1 -i 5 -w 120

This means that our ping command will terminate itself after 120 seconds, if the host could not have been reached by then.

Et voila! Our ping command will run for the specified time in a specified interval or until it will process one successful package. Happy pinging!