How can an internet connection be tested without pinging some website? I mean, what if there is a connection but the site is down? Is there a check for a connection with the
If your goal is to actually check for Internet access, many of the existing answers to this question are flawed. A few things you should be aware of:
With that in mind, I believe the best strategy is to contact several sites over an HTTPS connection and return true if any of those sites responds.
For example:
connected_to_internet() {
test_urls="\
https://www.google.com/ \
https://www.microsoft.com/ \
https://www.cloudflare.com/ \
"
processes="0"
pids=""
for test_url in $test_urls; do
curl --silent --head "$test_url" > /dev/null &
pids="$pids $!"
processes=$(($processes + 1))
done
while [ $processes -gt 0 ]; do
for pid in $pids; do
if ! ps | grep "^[[:blank:]]*$pid[[:blank:]]" > /dev/null; then
# Process no longer running
processes=$(($processes - 1))
pids=$(echo "$pids" | sed --regexp-extended "s/(^| )$pid($| )/ /g")
if wait $pid; then
# Success! We have a connection to at least one public site, so the
# internet is up. Ignore other exit statuses.
kill -TERM $pids > /dev/null 2>&1 || true
wait $pids
return 0
fi
fi
done
# wait -n $pids # Better than sleep, but not supported on all systems
sleep 0.1
done
return 1
}
Usage:
if connected_to_internet; then
echo "Connected to internet"
else
echo "No internet connection"
fi
Some notes about this approach:
Similarly to @Jesse's answer, this option might be much faster than any solution using ping
and perhaps slightly more efficient than @Jesse's answer.
find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1' {} \; | grep -q '1'
This command uses find
with -exec
to run command on all files not named *lo*
in /sys/class/net/
. These should be links to directories containing information about the available network interfaces on your machine.
The command being ran is an sh
command that checks the contents of the file carrier
in those directories. The value of $interface/carrier
has 3 meanings - Quoting:
It seems there are three states:
- ./carrier not readable (for instance when the interface is disabled in Network Manager).
- ./carrier contain "1" (when the interface is activated and it is connected to a WiFi network)
- ./carrier contain "0" (when the interface is activated and it is not connected to a WiFi network)
The first option is not taken care of in @Jesse's answer. The sh
command striped out is:
# Note: $0 == $interface
cat "$0"/carrier 2>&1
cat
is being used to check the contents of carrier
and redirect all output to standard output even when it fails because the file is not readable.
If grep -q
finds "1"
among those files it means there is at least 1 interface connected. The exit code of grep -q
will be the final exit code.
For example, using this command's exit status, you can use it start a gnubiff in your ~/.xprofile
only if you have an internet connection.
online() {
find /sys/class/net/ -maxdepth 1 -mindepth 1 ! -name "*lo*" -exec sh -c 'cat "$0"/carrier 2>&1 > /dev/null | grep -q "1" && exit 0' {} \;
}
online && gnubiff --systemtray --noconfigure &
This is notably faster than any solution posted here, and can be used to test a specific host too.
The trick is solving the IP using a less busy DNS solver than the one employed by ping
:
validateConnection () {
host="${1}"
ip=$(getent ahostsv4 "${host}" | awk '{ print $1 }' | head -n1)
ping -c1 "${ip}" 2>&1 >"/dev/null"
if [ "${?}" -ne 0 ]; then
echo "No connection to: ${host}" >&2
exit 1
fi
}
In Bash, using it's network wrapper through /dev/{udp,tcp}/host/port:
if : >/dev/tcp/8.8.8.8/53; then
echo 'Internet available.'
else
echo 'Offline.'
fi
(:
is the Bash no-op, because you just want to test the connection, but not processing.)
Ping your default gateway:
#!/bin/bash
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || echo error
I've written scripts before that simply use telnet to connect to port 80, then transmit the text:
HTTP/1.0 GET /index.html
followed by two CR/LF sequences.
Provided you get back some form of HTTP response, you can generally assume the site is functioning.