After my own study plus reviewing the two other answers here, I have concluded: there is no equivalent on Linux to the ping -o
command which exists on MacOS. Neither ping -c 1
nor fping
have the same behavior. The best you can do is emulate its behavior by using fping
or ping
in a loop which returns once the return code of either of those functions is 0
, indicating a ping success.
As I put in my comment here:
after testing fping
, I can say the following: fping 192.168.0.1
behaves like ping -c 4 -W 1 192.168.0.1
when the network is down, and like ping -c 1 192.168.0.1
when the network is up. fping
returns immediately if the network is up, and tries 4 times (1 initial try plus 3 retries, with a 1 second timeout after each attempt) if the network is down, returning after 4 timeouts = 4 sec total. ping -o
would return immediately if the network is up, but loop forever until the network comes up, then return, if the network was down.
So, leveraging the good work by @AlexPixel, here is my answer. This form catches the Ctrl + C kill signal to allow you to forcefully exit the infinite while
loop, it ensures you enter a parameter for the IP address when you run it, and it prints an attempt count and a message when the IP address comes alive.
ping_loop.sh:
#!/bin/bash
IP_ADDR="$1"
if [ -z $IP_ADDR ]; then
echo "You must enter the IP Address as the first parameter!"
exit 1
fi
to enable Ctrl + C inside the infinite while loop
trap 'printf "%s\n" "Ctr + C"; exit 2' SIGINT
count=0
while true; do
echo "Attempt: $count"
((count++))
ping -c 1 -W 5 "$IP_ADDR"
return_code=$?
if [ $return_code -eq 0 ]; then
echo "== DEVICE AT IP '$IP_ADDR' IS ALIVE! =="
break;
fi
done
Make executable with chmod +x ping_loop.sh
. "Install" it like this:
- Create a symlink in
~/bin
to this script so you can run it from anywhere:
cd /path/to/here
mkdir -p ~/bin
ln -si "${PWD}/ping_loop.sh" ~/bin/gs_ping_loop
ln -si "${PWD}/ping_loop.sh" ~/bin/ping_loop
- Now you can use the
ping_loop
or gs_ping_loop
command directly anywhere you like. This assumes ~/bin
is in your PATH
. If using Ubuntu and this is the first time creating ~/bin
, you may need to log out and log back in for your ~/.profile
file to make this take effect because it will automatically add that dir to your path.
Test it with:
ping_loop 10.0.0.1
Now you can read this other answers here to see how to forcefully bring that IP address up and down for ping
testing: How to create Ethernet interface at a specific IP address that I can ping and force to sometimes reply and sometimes not?.
One approach is this:
# block traffic to 10.0.0.1
sudo iptables -I OUTPUT 1 -p icmp --icmp-type echo-request -d 10.0.0.1 -j DROP
allow traffic to 10.0.0.1
NB: you must run this as many times as you ran the cmd above in order to
allow traffic. So, if you ran the cmd above an unknown number of times,
run this command as many times as it takes until you see:
iptables: Bad rule (does a matching rule exist in that chain?).
sudo iptables -D OUTPUT -p icmp --icmp-type echo-request -d 10.0.0.1 -j DROP
Sample output. I started with the traffic blocked via the command above, and then unblocked it with the other command above to make ping
pass and allow the script to end. You can see the == DEVICE AT IP '10.0.0.1' IS ALIVE! ==
print at the end.
$ gs_ping_loop 10.0.0.1
Attempt: 0
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
Attempt: 1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
Attempt: 2
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
Attempt: 3
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
Attempt: 4
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=4.20 ms
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 4.204/4.204/4.204/0.000 ms
== DEVICE AT IP '10.0.0.1' IS ALIVE! ==
Here is my final form of ping_loop.sh in my eRCaGuy_dotfiles repo: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/useful_scripts/ping_loop.sh <-- this is where I'll keep the latest and most-up-to-date version of this code!
See also:
- The 3 answers here, my own included, on how to turn an IP address's "pingability" on and off. This allows you to test the
ping_loop
script above: How to create Ethernet interface at a specific IP address that I can ping and force to sometimes reply and sometimes not?
fping
, I can say the following:fping 192.168.0.1
behaves likeping -c 4 -W 1 192.168.0.1
when the network is down, and likeping -c 1 192.168.0.1
when the network is up.fping
returns immediately if the network is up, and tries 4 times (1 initial try plus 3 retries, with a 1 second timeout after each attempt) if the network is down, returning after 4 timeouts = 4 sec total.ping -o
would return immediately if the network is up, but loop forever until the network comes up, then return, if the network was down. – Gabriel Staples Nov 18 '21 at 18:44ping
, MacOS'sping
, orfping
? – Gabriel Staples Nov 18 '21 at 22:51