How to check your public IP address from the terminal
Your public IP address is the one the rest of the internet sees. Checking it takes a single command, which is handy on servers without a browser and in scripts.
The quickest way: curl
The service at whatsmyip.haasje.net detects command-line clients such as curl and wget and answers with just your IP address as plain text, with no HTML around it.
curl -s https://whatsmyip.haasje.net
The -s flag silences the progress meter, so the output is only the address and easy to use in a script.
Force IPv4 or IPv6
If your connection has both IPv4 and IPv6, the address you get depends on which protocol curl picks. Ask for one explicitly:
curl -4 -s https://whatsmyip.haasje.net # IPv4 curl -6 -s https://whatsmyip.haasje.net # IPv6
When the IPv6 command fails or hangs, your network probably has no working IPv6 route. See IPv4 vs IPv6 for what that means.
Get JSON and filter it with jq
For more detail, such as the country and request headers, use the JSON endpoint:
curl -s https://whatsmyip.haasje.net/json | jq
Run it once to see the field names, then pick the one you need with jq -r '.fieldname'.
On Windows
Windows 10 and later include curl.exe. Type the .exe so PowerShell does not use its own curl alias:
curl.exe -s https://whatsmyip.haasje.net
The native PowerShell way is the JSON endpoint, which PowerShell turns into an object for you:
Invoke-RestMethod https://whatsmyip.haasje.net/json
Get notified when your IP changes
Most home connections get a dynamic address. This small script stores the last address it saw and prints a line when it changes. Run it from cron and send the output wherever you like.
#!/usr/bin/env bash
STATE=/var/tmp/last_public_ip
NOW=$(curl -4 -s --max-time 10 https://whatsmyip.haasje.net)
# Only continue when the answer looks like an IPv4 address
[[ "$NOW" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]] || exit 1
if [ "$NOW" != "$(cat "$STATE" 2>/dev/null)" ]; then
echo "$NOW" > "$STATE"
echo "Public IP changed to $NOW"
fi
Add it to your crontab to check every ten minutes:
*/10 * * * * /usr/local/bin/ipwatch.sh
The sanity check on the first lines matters: if the request fails, you do not want an empty string stored as your "new" address.
Troubleshooting
- Empty output: run the command without
-s, or add-v, to see whether DNS, TLS or a proxy is the problem. - Behind a corporate proxy: set the
https_proxyenvironment variable, or the address you see belongs to the proxy and not to your machine. - The address is not what you expected: a VPN, a proxy or carrier-grade NAT may be in between. The guide on public and private addresses explains how to tell.