Skip to content
shellmap

Get your public IP

Discover the IPv4 (or IPv6) address that the rest of the internet sees you originating from — for opening a firewall rule, debugging "why does this geo-blocked service reject me", checking whether a VPN / proxy is actually engaged, or seeding a DDNS update.

How to get your public ip in each shell

Bashunix
curl -s ifconfig.me

The 30-second answer. `-s` silences progress meter. Output is plain text, one IPv4 address. Failover endpoints (any of them works — pick by uptime preference): `curl -s icanhazip.com`, `curl -s api.ipify.org`, `curl -s checkip.amazonaws.com`, `curl -s ipinfo.io/ip`. For a script that needs reliability, race two: `(curl -s --max-time 3 ifconfig.me & curl -s --max-time 3 icanhazip.com & wait) | head -1`. For STRUCTURED data (city, ASN, ISP): `curl -s ipinfo.io` returns JSON; pipe through `jq .city`. For the LOCAL (LAN-side) IP, NOT public — that's a different question: `ip route get 1.1.1.1 | awk '{print $7; exit}'` (Linux) or `ipconfig getifaddr en0` (macOS).

Zshunix
curl -s ifconfig.me

Same external. macOS ships curl by default; Linux distros vary (`apt install curl` / `apk add curl`). For "is my VPN engaged?", compare before/after toggling: `curl -s ifconfig.me; sudo wg-quick up wg0; curl -s ifconfig.me` — if the second IP differs, the VPN is forwarding traffic. Some corporate proxies inject `X-Forwarded-For`; `ifconfig.me` returns the EDGE-of-tunnel IP, not your true origin — `curl -s ifconfig.me/all` returns headers + IP for diagnosis.

Fishunix
curl -s ifconfig.me

Same external. Fish-friendly variable capture: `set my_ip (curl -s ifconfig.me); echo "Public IP: $my_ip"`. For an interactive prompt: a fish function `function pubip; curl -s ifconfig.me; echo; end` (the trailing `echo` adds a newline since `ifconfig.me` does not).

PowerShellwindows
Invoke-RestMethod ifconfig.me/ip

`Invoke-RestMethod` is the pwsh-native HTTP client (no need for curl on Windows). `ifconfig.me/ip` returns plain text (`Invoke-RestMethod` returns the string directly). `ifconfig.me` WITHOUT `/ip` returns an HTML page on pwsh because pwsh sends a browser-like User-Agent by default — use `/ip` for the plain endpoint, or pass `-Headers @{"User-Agent"="curl/7"}` to mimic curl. For STRUCTURED: `Invoke-RestMethod ipinfo.io | Select city, region, org`. On pwsh 5.1 / Windows 7-8, `Invoke-RestMethod` uses the old IE rendering engine — pass `-UseBasicParsing` to avoid the COM-IE dependency.

cmd.exewindows
curl -s ifconfig.me

Windows 10 1803+ ships `curl.exe` in `C:\Windows\System32` — so the bash one-liner works directly in cmd. On older Windows: shell out to pwsh (`powershell -NoProfile -Command "Invoke-RestMethod ifconfig.me/ip"`). For a NO-HTTP-DEPENDENCY trick: `nslookup myip.opendns.com resolver1.opendns.com` — OpenDNS resolvers return YOUR public IP as the A record for the special name `myip.opendns.com`. Parse: `for /f "tokens=2 delims=:" %i in ('nslookup myip.opendns.com resolver1.opendns.com ^| findstr Address ^| findstr /v "#53"') do @echo %i`. Useful in locked-down environments where outbound HTTP is blocked but DNS to 208.67.222.222 is allowed.

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • **IPv4 vs IPv6**: most "public IP" endpoints return IPv4 by default — `curl -s ifconfig.me` gives `203.0.113.42` even on a dual-stack host. For IPv6 explicitly: `curl -s ipv6.ifconfig.me` (or `curl -6 -s ifconfig.me`, but the v6-only endpoint is more reliable when the host has both addresses). For DUAL output: `echo "v4: $(curl -s4 ifconfig.me)"; echo "v6: $(curl -s6 ifconfig.me)"` — note `-4` / `-6` force the curl resolution, NOT the endpoint. If your network has no IPv6 connectivity, the v6 call will timeout — add `--max-time 3`.
  • **Behind NAT, public IP ≠ machine IP**: home networks, mobile carriers, and corporate LANs put you behind NAT. `ifconfig.me` returns the **egress** IP (the address your traffic exits the NAT as) — which can be SHARED with thousands of other users on carrier-grade NAT (CGNAT, common on mobile / fiber). The LOCAL machine IP (`192.168.x.x`, `10.x.x.x`, `172.16-31.x.x`) is what your machine sees; the egress IP is what services see. These are usually different. For peer-to-peer NAT traversal (WebRTC, BitTorrent), STUN / TURN servers tell you both.
  • **Endpoint reliability and failover**: any single endpoint can rate-limit or go down. For SCRIPTED use, prefer multiple endpoints with timeouts: `for ep in ifconfig.me icanhazip.com checkip.amazonaws.com api.ipify.org; do ip=$(curl -s --max-time 3 "$ep"); [ -n "$ip" ] && { echo "$ip"; break; }; done`. AWS's `checkip.amazonaws.com` is the most reliable for production (AWS-uptime SLA, no rate limit) — the others are community-run and may throttle. For HIGH-volume polling (DDNS, monitoring), self-host: a 10-line nginx config returning `$remote_addr` does it.
  • **Privacy implications**: third-party "what is my IP" endpoints LOG every request — your public IP is correlatable with timestamp + UA. For sensitive contexts (Tor, opsec audits), DO NOT use third-party endpoints — query a server you control, OR use the cmd nslookup-OpenDNS trick (DNS-over-UDP to OpenDNS, less surface area than an HTTPS GET). For automated DDNS updates, prefer your DDNS provider's OWN check-IP endpoint (they already see your IP via the update request, so the check adds zero new exposure).

Related commands

Related tasks