Short answer: ip -brief addr show lists every interface and its address in one short line each; hostname -I prints just the addresses, nothing else; and neither one tells you your public IP if the server sits behind NAT or a cloud provider’s private network — for that, ask an outside server with curl ifconfig.me.
| Task | Command |
|---|---|
| Every interface, short form | ip -brief addr show |
| Every interface, full detail | ip addr show |
| One interface only | ip addr show eth0 |
| Addresses only, no interface names | hostname -I |
| Default route (which interface faces the internet) | ip route get 1.1.1.1 |
| Public IP, as seen from outside | curl ifconfig.me |
| Public IP, JSON with more detail | curl ipinfo.io |
| Who owns a given public IP | whois 203.0.113.10 |
| Legacy tool (often not installed) | ifconfig |
ip addr: the current tool
ip -brief addr showlo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 203.0.113.10/24 2001:db8::a1b2/64 fe80::be24:11ff:fe02:713b/64ip addr show2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether be:24:11:02:71:3b brd ff:ff:ff:ff:ff:ff
inet 203.0.113.10/24 metric 100 brd 203.0.113.255 scope global dynamic eth0
valid_lft 3542sec preferred_lft 3542sec
inet6 2001:db8::a1b2/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 86389sec preferred_lft 14389sec
inet6 fe80::be24:11ff:fe02:713b/64 scope link
valid_lft forever preferred_lft forever- lo is always the loopback interface,
127.0.0.1— never your real address, even on the shortest list. - The
/24after an address is the subnet mask in CIDR notation, not part of the IP itself. fe80::…is a link-local IPv6 address, generated automatically on every interface and only reachable from the same local network — never the address to give out for anything.dynamicnext to an address means DHCP (or, for IPv6, SLAAC) assigned it and it can change;staticmeans it was set by hand in the interface’s own configuration and stays fixed.
One interface by name
ip addr show eth0
ip -4 addr show eth0 # IPv4 only
ip -6 addr show eth0 # IPv6 onlyInterface names vary by provider and image: eth0 is common on KVM virtual machines, Ubuntu’s predictable naming scheme produces names like enp1s0 instead. ip -brief link show lists every interface name that exists on the box before you pick one.
hostname -I: just the addresses
hostname -I203.0.113.10 2001:db8::a1b2 fe80::be24:11ff:fe02:713b%eth0Capital -I (not the lowercase -i, which does something else entirely and is deprecated) prints every address of every interface as a plain space-separated list — the form to reach for inside a script, since there is nothing to parse out of it:
hostname -I | awk '{print $1}'Your public IP: ask outside the server
ip addr and hostname -I only ever show you the address this machine has, which on a VPS behind a cloud NAT, a home router, or a Docker container is a private address — not what the rest of the internet sees you as. To get that, ask a server outside your own network:
curl ifconfig.me
curl -4 ifconfig.me # force IPv4
curl -6 ifconfig.me # force IPv6
curl ipinfo.io # adds city, ASN and organisation as JSONOn a typical KVM VPS, where the public IP is configured directly on the network interface rather than behind NAT, ip addr already shows the same address curl ifconfig.me would report — the two only diverge behind NAT or a cloud load balancer. The my IP tool runs the same outside check from a browser, with no terminal needed, and shows IPv4 and IPv6 side by side.
Which interface actually talks to the internet?
ip route get 1.1.1.11.1.1.1 via 203.0.113.1 dev eth0 src 203.0.113.10 uid 0
cacheOn a server with one network card this is obvious, but on anything with several (a VPN interface, a Docker bridge, a second NIC on an internal VLAN) this is the reliable way to find the one your traffic actually leaves through, and the src field is the address it leaves with — which is the address a remote server sees, regardless of what any other interface shows.
ifconfig still works, where it is installed
ifconfigifconfig is the older BSD-style tool and is not installed by default on current Debian, Ubuntu, Rocky or AlmaLinux minimal images — it ships in the net-tools package, which the ip command (from iproute2) replaced over a decade ago in every Linux distribution’s own documentation. If a script or an old habit still needs it, ifconfig: command not found has the install line for each distribution; for anything new, write ip commands instead.
Checking that a domain actually points at this IP
Knowing the server’s own IP is usually step one of pointing a domain at it or checking that DNS has caught up:
dig +short example.com
nslookup example.comPointing a domain at a VPS covers the DNS side end to end, from the A record to waiting out the TTL.
Using the address in a script
PUBLIC_IP=$(curl -s ifconfig.me)
LOCAL_IP=$(hostname -I | awk '{print $1}')
MAIN_IP=$(ip -4 -j addr show eth0 | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['addr_info'][0]['local'])")-j on any ip subcommand prints JSON instead of the usual text, which is worth reaching for the moment a script needs to pick one specific field reliably rather than parsing columns that can shift between distributions.
Frequently asked
What is the quickest command to see my IP address on Linux?
ip -brief addr show lists every interface with its address on one short line each. hostname -I is shorter still when you only need the addresses themselves, with no interface names, which also makes it the easier one to use inside a script.
Why does ip addr show a different IP than curl ifconfig.me?
ip addr only ever shows the address assigned to this machine's own network interface, which behind NAT — a home router, a cloud load balancer, a Docker container — is a private address, not what the rest of the internet sees. curl ifconfig.me asks a server outside your network and reports the address it saw you connect from, which is the real public IP in that case.
Why is ifconfig not found on my server?
ifconfig ships in the net-tools package, which current Debian, Ubuntu, Rocky and AlmaLinux minimal images do not install by default — it was replaced by the ip command (from iproute2) in every current distribution's own documentation over a decade ago. Install net-tools if a script still needs it specifically, or rewrite the script around ip.
How do I find which network interface actually reaches the internet?
ip route get 1.1.1.1 shows the interface and source address your traffic really leaves through, which matters once a server has more than one network interface — a VPN, a Docker bridge, a second NIC — and the obvious-looking first interface in the list is not necessarily the one in use.