How to Check Internet Connection in Linux Command Line and Shell Script

Deepak Prasad
Tested on RHEL 10.2 (Coughlan)
Package iproute 6.17.0-2.el10
iputils 20240905-5.el10
curl 8.12.1-4.el10
bind-utils 9.18.33-15.el10_2.2
wget 1.24.5-5.el10
nmap-ncat 7.92-5.el10
Applies to RHEL, Rocky Linux, AlmaLinux, Fedora, Debian, Ubuntu, and other Linux distributions with standard networking tools
Privilege Normal user for these checks; elevated privileges may be required only if local system permissions restrict a diagnostic tool
Scope Hostname-first internet checks with curl, ping, and wget, plus routing, DNS, and TCP isolation when those fail. Does not cover proxy server setup, Wi-Fi driver troubleshooting, or full packet capture analysis.
Related guides curl command
ping command
wget command
check whether a port is open
nmcli examples

For a normal “is the internet up?” check, use a hostname such as google.com — you do not need to look up 8.8.8.8 or 1.1.1.1 first. Reserve IP-only probes for later, when a hostname test fails and you want to know whether DNS or routing is the problem.


Quick answer: is the internet up?

The fastest reliable check on most Linux servers is a short HTTPS request to Google's connectivity endpoint:

bash
curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204

The command prints nothing when it succeeds, so confirm the exit status:

bash
echo $?

Sample output:

output
0

Exit status 0 means the host reached the internet over HTTPS. generate_204 returns HTTP 204 with no body, so it is lighter than fetching a full home page.

Many people still try ping google.com first. That is fine for a quick glance, but ICMP to public hosts is often blocked even when web access works:

bash
ping -c 1 -W 2 google.com

On the RHEL 10.2 lab guest used here, curl to generate_204 succeeded while ICMP to google.com showed 100% packet loss — the same pattern you may see on filtered networks.


Check internet connection in a shell script

For automation, keep the probe short and branch on the exit code. This pattern uses the same hostname-based HTTPS check:

bash
#!/usr/bin/env bash

if curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204; then
  echo "online: https check succeeded"
else
  echo "offline: https check failed"
fi

Sample output when the host can reach the internet:

output
online: https check succeeded

Wrap the same test in a function when a larger script needs to reuse it:

bash
check_internet_access() {
  curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204
}

Call the function and branch on its exit status:

bash
if check_internet_access; then
  echo "online: https check succeeded"
else
  echo "offline: https check failed"
fi

For control-flow basics, see Bash if else examples and Bash function examples.


When the quick check fails, work down the stack

One command rarely proves every layer is healthy. After curl or ping to a hostname fails, work in this order:

Step Question Tool
1 Does the kernel know how to reach the internet? ip route get
2 Can the host resolve names? getent hosts or dig
3 Can the host reach a public IP without DNS? ping or nc to 1.1.1.1
4 Does HTTPS work end to end? curl to a hostname

You only need step 3 when step 2 fails or when you suspect DNS is broken. That is the rare case where checking 1.1.1.1 or 8.8.8.8 directly makes sense — not because you memorized the address, but because you are separating “routing works” from “DNS works.”


Check whether Linux has a route to the internet

ip route get asks the kernel which interface, gateway, and source address it would use. It does not contact the remote host, so using a well-known IP here is fine even before DNS is tested:

bash
ip route get 1.1.1.1

Sample output:

output
1.1.1.1 via 10.0.2.2 dev enp0s3 src 10.0.2.15 uid 0
    cache

The via gateway and dev interface confirm a route exists toward the public internet. That still does not prove DNS, firewall rules, or HTTPS access works.

If the command reports the network is unreachable, inspect the IP address, default gateway, and link state first. See nmcli examples when NetworkManager manages the connection.

Ping the default gateway next when you want to confirm local L3 connectivity before blaming the upstream link:

bash
ping -c 1 -W 2 10.0.2.2

Sample output:

output
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.640 ms

--- 10.0.2.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.640/0.640/0.640/0.000 ms

Check DNS resolution from the command line

DNS answers a different question than “is the internet up?” — can this host convert google.com into an address?

Test through the normal system resolver with getent:

bash
getent hosts google.com

Sample output:

output
142.250.67.46   google.com

For DNS-focused output, use dig:

bash
dig +short google.com A

Sample output:

output
142.250.67.46

If getent hosts google.com fails but ip route get looked fine, check /etc/resolv.conf, NetworkManager DNS settings, or your local resolver before you rerun curl. For BIND administration, see configure a BIND DNS server.


Test reachability without DNS

When hostname checks fail, ping or open a TCP connection to a public IP to see whether the problem is DNS or something lower in the stack.

Ping a public resolver without using DNS:

bash
ping -c 1 -W 2 1.1.1.1

On the lab host, ICMP to 1.1.1.1 was filtered even though HTTPS and TCP port 443 succeeded:

output
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.

--- 1.1.1.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

When public ICMP is blocked, use a TCP port check instead. With nc (Ncat on RHEL 10):

bash
nc -vz -w 3 1.1.1.1 443

Sample output:

output
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Connected to 1.1.1.1:443.
Ncat: 0 bytes sent, 0 bytes received in 0.02 seconds.

Bash /dev/tcp works without netcat. This is a Bash feature, not POSIX sh:

bash
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/1.1.1.1/443'

The command exits silently on success, so check the status:

bash
echo $?

Sample output:

output
0

A successful TCP connection proves the remote IP and port are reachable. It does not prove certificate trust, HTTP responses, or proxy configuration. For broader port troubleshooting, see check whether a port is open in Linux. For more ping options on hostname checks, see the ping command guide.


Check real HTTPS access with curl

Most applications need HTTP or HTTPS to a hostname, not only ICMP or raw TCP. This curl request fetches https://example.com, discards the body, and prints the status code and remote IP:

bash
curl -fsS --max-time 5 -o /dev/null -w 'http_code=%{http_code} remote_ip=%{remote_ip}\n' https://example.com

Sample output:

output
http_code=200 remote_ip=87.254.212.120

http_code=200 means the HTTPS request succeeded. For a minimal connectivity probe in scripts, generate_204 is still the better default than a random home page:

bash
curl -fsS --max-time 5 -o /dev/null -w 'http_code=%{http_code}\n' https://www.google.com/generate_204

Sample output:

output
http_code=204

Useful flags in these examples:

  • -f — fail on HTTP error responses such as 404 or 500
  • -sS — quiet normal output but still show errors
  • --max-time 5 — prevent scripts from hanging
  • -o /dev/null — discard the page body
  • -w — print only the fields you choose

See the curl command guide for more options. If curl is missing, see install cURL on Ubuntu or curl command not found.

IMPORTANT
If the host must use a proxy, configure http_proxy, https_proxy, or curl proxy options before treating a direct curl test as authoritative. See set up http_proxy and https_proxy.

If curl reports SSL certificate problem: unable to get local issuer certificate while routing looks fine, HTTPS trust is broken — common behind corporate TLS inspection. See fix curl SSL certificate problem behind corporate proxy.


When a website blocks bot or script traffic

A failed curl to a normal website does not always mean the host is offline. Many sites return 403 Forbidden, 503 Service Unavailable, or a challenge page when they detect script clients, missing cookies, or the default curl User-Agent. That is application policy, not proof that routing or DNS is broken.

For generic internet checks in scripts, use endpoints meant for connectivity probes instead of arbitrary home pages:

bash
curl -fsS --max-time 5 -o /dev/null -w 'http_code=%{http_code}\n' https://www.google.com/generate_204

http_code=204 means the HTTPS path works. Cloudflare's trace endpoint is another neutral option when you want a short text response:

bash
curl -fsS --max-time 5 https://cloudflare.com/cdn-cgi/trace

Sample output (trimmed):

output
fl=1166f85
h=cloudflare.com
ip=87.254.212.121
ts=1786875935.000
visit_scheme=https
uag=curl/8.12.1

The ip= line confirms your outbound public address as seen by the remote service.

If HTTP checks keep failing but nc -vz 1.1.1.1 443 succeeds, outbound TCP connectivity to port 443 works. DNS resolution, TLS negotiation, certificate validation, and the HTTP request may still fail separately. In that case:

  • Use generate_204, cdn-cgi/trace, or a TCP port check for a generic online/offline probe
  • Test your own application's URL only when that specific service is what you need to verify
  • Avoid relying on spoofed browser User-Agent strings as your primary fix; sites change bot rules often and some networks forbid impersonation in automation

Check internet access with wget

wget --spider checks whether a URL is reachable without saving the page. Use a hostname, not a bare IP:

bash
wget -q --spider --timeout=5 https://www.google.com/generate_204

wget prints nothing when the check succeeds, so read the exit status:

bash
echo $?

Sample output:

output
0

Exit status 0 means the URL check succeeded. A non-zero status still requires reading the error message to see whether DNS, TCP, TLS, or HTTP failed. See wget command in Linux or wget command not found if the tool is missing.


Troubleshooting

Symptom Likely cause Fix
curl to google.com fails but getent hosts google.com works Firewall, proxy, TLS, or blocked port 443 Test generate_204; check proxy env vars and corporate TLS inspection
getent hosts fails but nc -vz 1.1.1.1 443 succeeds DNS misconfiguration Fix /etc/resolv.conf or NetworkManager DNS settings
ping google.com fails but curl succeeds ICMP blocked to public hosts Use HTTPS or TCP checks instead of ping for internet proof
ip route get reports network unreachable Missing default route or down interface Fix IP, gateway, or link with NetworkManager or static config
curl returns HTTP 403 on a normal site Bot filtering on that host Use generate_204, cdn-cgi/trace, or test your app's URL
ping works but curl fails ICMP allowed, HTTP/HTTPS blocked Check outbound 80/443, proxy, and TLS trust store

References


Summary

Checking internet connection on Linux should start the way most operators actually work: probe a hostname with curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204, or try ping google.com when you want a fast ICMP glance. You do not need to look up 8.8.8.8 or 1.1.1.1 first, and you should not treat dig or getent as proof the internet works — those tools only test name resolution.

When the quick check fails, work down the stack. Confirm routing with ip route get, test DNS with getent hosts google.com, and use IP-only ping or nc probes only to separate DNS problems from upstream reachability. On filtered networks, ICMP to public addresses often fails while HTTPS still works, which is why script checks should prefer generate_204 over ping.

If a normal website returns 403 to curl but opens in a browser, treat that as bot filtering on that host — not as proof the server lacks internet access. Fall back to generate_204, cdn-cgi/trace, or a TCP port check for a generic probe. Deeper path analysis belongs to tools such as traceroute and tcpdump; see the tcpdump command guide when you need that level of detail.


Frequently Asked Questions

1. What is the best Linux command to check internet connection in a shell script?

curl is usually the best choice. Probe https://www.google.com/generate_204 with a short timeout — it tests real HTTPS access and returns a useful exit code without downloading a page body.

2. Should I ping 8.8.8.8 or google.com to check internet access?

Start with a hostname such as google.com in curl or ping. You do not need to look up a public IP first. Reserve 8.8.8.8 or 1.1.1.1 for later when you are isolating DNS from routing — not as the first everyday check.

3. Why does ping work but curl or wget fails?

Ping uses ICMP, while curl and wget use HTTP or HTTPS over TCP. A firewall, proxy, DNS issue, TLS inspection device, or blocked outbound port 80 or 443 can allow ping while breaking web access.

4. Why does DNS lookup work but the server still has no internet?

DNS lookup only proves that the system can resolve a name. The resolved service may still be unreachable because of routing, firewall, proxy, TCP, TLS, or remote server issues.

5. Can I check internet connectivity without ping?

Yes. Use curl or wget against a hostname such as google.com, getent or dig when you need to test DNS, and nc or Bash dev tcp only when you are isolating DNS from raw TCP reachability.

6. Why does curl fail with HTTP 403 on a website that opens in a browser?

Many sites block automated clients, default curl User-Agent strings, or requests without browser cookies. Use a purpose-built connectivity endpoint such as generate_204 or cdn-cgi/trace, or fall back to a TCP port check when you only need to prove outbound connectivity.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration