I have searched and am having troubles finding an answer, im sorry if this is a novice question...
I am creating a program to automatically reconnect to my VPN and mount required drives in the event of a disconnect. So far, it works perfect (checks every 60 seconds or so for the VPN)
Problem comes when I am not near wifi, it keeps yelling at me that it cannot connect. Is there a bit of code that exists to simply check if I am connected to the internet before running the rest of the script, and if I am not connected to the internet, to just leave me alone until I reconnect? Most of what I can find looks to ping a website (which im not adverse to doing, especially if i can use it to ping the VPN) but does not seem to work in the background without notifying me that it still cannot see the server.
There a few ways you can verify internet connectivity; the simplest of which is to just ping
an external host (one that you expect to be up), then check the status code.
Replace
www.google.com
withyour.vpn.host
or any host you desire in the following examples.
host="www.google.com"
ping -c1 "$host" &> /dev/null
if [ $? -eq 0 ]; then
# connection is UP
else
# connection is DOWN
fi
Alternatively, you can use nc
to specify a custom port number and connection timeout period:
# Note: w/ the macOS BSD version of `nc` you use the `-G` flag rather than the `-w` flag to specify the connection timeout.
host="www.google.com"
port=80
timeout=5
nc -G$timeout -z "$host" "$port" &> /dev/null
if [ $? -eq 0 ]; then
# connection is UP
else
# connection is DOWN
fi
If you don't want to rely on external commands, and instead decide you want to leverage bash
native TCP sockets (and also specify a custom port number and connection timeout period):
host="www.google.com"
port=80
timeout=5
echo > "/dev/tcp/$host/$port" & pid="$!"
{ sleep "$timeout"; kill "$pid"; } &> /dev/null &
wait "$pid" &> /dev/null
if [ $? -eq 0 ]; then
# connection is UP
else
# connection is DOWN
fi
If you simply want to check if you are connected to a WiFi network on a specific interface (macOS ONLY), you can use:
# Replace `en0` with the interface you want to check
networksetup -getairportnetwork en0
# There is no convenient status code check that I am aware of here. You can
# save the output to a variable and grep for the word: "off"
# I don't think this is what you need but to check if Wi-Fi is `enabled` use:
networksetup -getairportpower en0
# Again, you will need to grep for the word: "off"
For a more robust alternative, I would suggest you take a look at a simple bash utility I wrote called
check
written specifically for checking the connectivity of proxy servers. Spoiler: there is no magic here though; under-the-hood I am just leveraging bash native TCP/UDP sockets, albeit wrapped with a convenient set of options and insightful usage documentation.
Finally, one slightly esoteric alternative that I have employed in macOS launchd daemons to pause execution (i.e. endlessly loop) until an internet connection is available:
CheckForNetwork is shell function located in
/etc/rc.common
to check inet addresses. It is a useful utility but will not ensure internet connectivity (only ip address assignment) as opposed to the aforementioned alternatives which will verify connectivity.
. /etc/rc.common
CheckForNetwork
while [ "${NETWORKUP}" != "-YES-" ]; do
sleep 60
NETWORKUP=
CheckForNetwork
done