Linux 查看 IP 地址:ip addr、hostname -I 与 curl
- 2026年10月30日
- 09:00
- 作者: Adrien Roche
- 网络

用 ip addr 查看 Linux 的 IP 地址
在任何当前的 Linux 发行版上,回答“我的 IP 地址是多少”的命令是来自 iproute2 软件包的 ip。它在所有主流发行版中默认安装,无需 root 即可使用,本文其他命令要么是它的封装,要么已被它取代。最基本的形式会列出每块网卡及其全部地址:
ip addr show
ip a # same thing, shorter在只有一块网卡的服务器上,输出如下所示(valid_lft 生存期相关的行已省略):
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
inet 203.0.113.25/24 brd 203.0.113.255 scope global eth0
inet6 2001:db8:1::25/64 scope global
inet6 fe80::5054:ff:fe12:3456/64 scope link如何读懂它:
- 网卡名称。
lo是回环接口,地址始终为127.0.0.1,只能从本机访问。这里真正的网卡是eth0;在可预测网卡命名下,它可能显示为ens3、enp0s3或eno1,无线网卡则以wl开头。 inet是 IPv4 地址,inet6是 IPv6 地址。/24后缀是 CIDR 表示法中的前缀长度,也就是子网掩码255.255.255.0的现代写法。scope global表示该地址在本机之外可路由;scope link(fe80::那一行)仅在所连接的网段内有效;scope host表示回环。state UP加上LOWER_UP表示网卡已启用且链路已连通。state DOWN或NO-CARRIER通常正是网卡完全没有地址的原因。
常用变体:
ip -4 addr # IPv4 only
ip -6 addr # IPv6 only
ip -br -4 addr # one line per interface
ip -4 addr show dev eth0 # a single interface当存在多块网卡时(在运行 Docker 的 VPS 上这很常见),简洁模式(-br)是查看 Linux IP 地址最快的方式:
$ ip -br -4 addr
lo UNKNOWN 127.0.0.1/8
eth0 UP 203.0.113.25/24
docker0 DOWN 172.17.0.1/16hostname -I:只看地址
如果你只需要地址,hostname -I(大写 I)会把所有已配置的地址打印在一行中,以空格分隔,不包含回环地址和 IPv6 链路本地地址:
$ hostname -I
203.0.113.25 2001:db8:1::25有两点需要注意。小写的 hostname -i 是另一回事:它通过 /etc/hosts 和 DNS 解析本机主机名,在 Debian 和 Ubuntu 上通常返回 127.0.1.1。另外,hostname -I 输出地址的顺序没有任何保证,还会包含 docker0 之类的虚拟网桥,因此 hostname -I | awk '{print $1}' 只是给人看的捷径,而不是脚本可靠的“主 IP”。这个选项并非 POSIX 标准:Debian、Ubuntu、Fedora 和 RHEL 都有,但 Alpine 这类基于 BusyBox 的精简镜像可能没有。
ifconfig、nmcli 与 networkctl
ifconfig(已废弃,net-tools)
ifconfig 是老教程里常见的命令。它属于 net-tools,多年来一直被 iproute2 取代,在当前的 Ubuntu、Debian 和 Fedora/RHEL 版本中已不再默认安装。如果它返回 command not found,请改用 ip 或安装该软件包:
sudo apt install net-tools # Debian / Ubuntu
sudo dnf install net-tools # Fedora / RHEL / Rocky / Alma$ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 203.0.113.25 netmask 255.255.255.0 broadcast 203.0.113.255
inet6 fe80::5054:ff:fe12:3456 prefixlen 64 scopeid 0x20<link>输出可读性不错,但有一个实际限制:ifconfig 每块网卡只显示一个 IPv4 地址。用 ip addr add 添加的辅助地址(在拥有多个公网 IP 的 VPS 上很常见)它完全看不到。
nmcli 与 networkctl
桌面系统以及 Fedora/RHEL 系服务器使用 NetworkManager 管理网络;Ubuntu Server 在 systemd-networkd 之上使用 netplan,许多 VPS 镜像也采用同样的模式。两者都有状态工具,可以在一个区块内显示地址、网关和 DNS:
nmcli device show eth0
nmcli -g IP4.ADDRESS device show eth0 # NetworkManager: just the address field
networkctl status eth0 # systemd-networkd-g(--get-values)参数只打印某个字段的原始值,包含前缀长度,非常适合脚本使用。如果你不确定机器使用的是哪一套网络栈,甚至不确定是哪个发行版和版本,请先从命令行确认操作系统版本;答案决定了系统上存在哪个工具。
用 curl 查看公网 IP 地址
上面所有命令报告的都是网卡上配置的地址。在大多数 VPS 上,公网 IPv4 直接分配到网卡,因此它也就是互联网看到的地址。而在家庭、办公室或某些云环境中,网卡上是 RFC 1918 私有段(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)的地址,由路由器或 1:1 NAT 在出口做转换。查看公网侧唯一可靠的方式是询问外部服务:
curl -4 icanhazip.com
curl -4 ifconfig.me/ip
curl -4 https://api.ipify.org
curl -6 icanhazip.com # public IPv6, if the host has one-4 和 -6 参数强制指定地址族,这在双栈主机上很重要:不加它们时,curl 可能优先使用 IPv6,返回你意料之外的地址。icanhazip.com 自 2021 年起由 Cloudflare 运营,返回纯文本。请把结果理解为“我的流量从哪个地址出去”:在 VPN 或代理之后,它是出口节点的地址,而不是你的 ISP 地址。
IPv6:全局地址与链路本地地址
几乎每块 Linux 网卡都会显示至少一行 inet6,它常被误认为是公网 IPv6 地址。以 fe80:: 开头并标记 scope link 的那一行是链路本地地址:每块网卡都会自动生成一个,它只在所连接的网络内有效,永远无法从互联网访问。公网 IPv6 地址标记为 scope global,并以 2 或 3 开头,因为全局单播地址空间是 2000::/3。
ip -6 addr show scope global
ip -6 route show default如果第一条命令没有任何输出,说明这台机器没有可路由的 IPv6,curl -6 会失败。桌面系统上标记为 temporary 的额外全局地址来自隐私扩展;服务器会关闭该功能,让地址保持稳定,便于 DNS 和防火墙规则使用。
默认网关、路由与 DNS
光有地址并不能说明机器是否能访问到任何东西。路由表才能说明这一点,用 ip route(简写 ip r)即可打印:
$ ip route
default via 203.0.113.1 dev eth0 proto static
203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.25default via 那一行是默认网关,即没有更精确路由匹配时所有数据包使用的路由器。第二行是配置地址时由内核添加的;其中的 src 字段是主机在该网络上优先使用的源地址。最实用的技巧正基于此:直接询问内核,对某个目的地址它会使用哪个源地址。
$ ip route get 1.1.1.1
1.1.1.1 via 203.0.113.1 dev eth0 src 203.0.113.25 uid 1000
cache根据定义,这个 src 值就是本机通往互联网的出口地址,无论存在多少网卡、网桥或隧道。至于 DNS,/etc/resolv.conf 依然是查看的地方,但在运行 systemd-resolved 的系统上(Ubuntu 18.04 起、较新的 Fedora),它只包含本地存根 127.0.0.53;真正的上游解析器由 resolvectl status 显示,在 NetworkManager 主机上也可以看 nmcli device show 的 IP4.DNS 字段。
脚本编写:把 IP 地址存入变量
交互式输出是给人看的;脚本需要的是一个干净的地址,不带任何多余内容。下面这些写法从最简单到最健壮,都经得起考验:
# One interface, IPv4, prefix length stripped
IP=$(ip -4 -o addr show dev eth0 | awk '{print $4}' | cut -d/ -f1)
# Robust: the source address used to reach the internet
IP=$(ip route get 1.1.1.1 | awk '{for (i=1; i<=NF; i++) if ($i == "src") {print $(i+1); exit}}')
# Same thing with JSON output and jq
IP=$(ip -j route get 1.1.1.1 | jq -r '.[0].prefsrc')
# Public IP, with a timeout so the script never hangs offline
PUBLIC_IP=$(curl -4 -s --max-time 5 https://icanhazip.com)-o 参数让 ip 每行打印一个地址,从而保证 awk 的字段位置稳定;如果网卡上有多个 IPv4 地址,可加上 head -n 1。-j 参数让 ip 输出 JSON,再由 jq 按名称取字段。凡是要在多台机器上运行的脚本,都优先使用这种形式:网卡名称因主机而异,字段名称却不会变。
| 命令 | 显示内容 | 适用场景 |
|---|---|---|
ip addr / ip -br -4 addr | 所有网卡、全部地址及状态 | 日常使用,全局视图 |
hostname -I | 一行显示所有地址 | 快速查看 |
ip route get 1.1.1.1 | 通往互联网所使用的源地址 | 脚本、多网卡主机 |
ifconfig | 每块网卡一个 IPv4(已废弃) | 老旧系统、旧教程 |
curl -4 icanhazip.com | 互联网看到的公网 IPv4 | NAT、VPN、确认 VPS 地址 |
在 VPS 上有什么不同
在拥有独享 IPv4 的 VPS 上,ip -4 addr、hostname -I 和 curl -4 icanhazip.com 应当返回同一个地址,因为公网 IP 直接配置在网卡上,中间没有 NAT。如果三者不一致,说明路径中有东西:服务商侧的 NAT、被遗忘的 VPN 客户端,或是抢占了 hostname -I 第一个位置的 Docker 网桥。
确认地址之后,还要检查两件事。第一,它是否真的可达、开放了哪些端口,这与地址是否已配置是两回事:在内部用 ss -tulpn、在外部用 nmap 检查 Linux 服务器的开放端口。第二,反向 DNS。查询你的地址对应的 PTR 记录:
dig -x 203.0.113.25 +short全新的 VPS 通常返回服务商的通用名称,或者什么都不返回。如果服务器要发送邮件或对外提供任何公共服务,请设置主机名和反向 DNS 使二者一致;尤其是外发邮件,PTR 记录与 HELO 名称不一致时经常会被拒收。
要把这些命令练成条件反射,最快的办法是拥有一台地址专属且不会变动的服务器。rdp.monster 的 Linux VPS 提供独享 IPv4、完整 root 权限、独享 CPU 与内存、无限流量(公平使用)且无需 KYC,支持加密货币付款,每月 $8.99 起。付款确认后约 10 秒服务器即上线,你在上面运行的第一条 ip -br -4 addr 触手可及。
常见问题
为什么 hostname -I 显示了不止一个 IP 地址?
hostname -I 会打印所有网卡上的全部地址,只排除回环地址和 IPv6 链路本地地址,因此装有 Docker、libvirt、VPN 客户端或第二块网卡的机器会显示多个地址。docker0 贡献 172.17.0.1,virbr0 通常是 192.168.122.1,双栈主机还会加上它的全局 IPv6 地址。顺序没有保证。当你需要流量真正出去所用的地址时,请运行 ip route get 1.1.1.1 并读取其中的 src 字段。为什么 Ubuntu 上 ifconfig 提示 command not found?
ifconfig 命令属于 net-tools 软件包,它已被 iproute2 取代,并且不在当前 Ubuntu、Debian 和 Fedora/RHEL 版本的默认安装中。替代命令是随处可用的 ip addr。如果某个脚本或旧习惯确实需要它,可以用 sudo apt install net-tools 或 sudo dnf install net-tools 安装,但要记住 ifconfig 每块网卡只显示一个 IPv4 地址,并且会隐藏通过 ip addr add 添加的辅助地址。为什么 hostname -i 返回 127.0.1.1?
hostname -i 根本不查看网络:它像任何应用程序一样,通过 /etc/hosts 再经 DNS 解析系统主机名。Debian 和 Ubuntu 安装程序会添加一行,把主机名映射到 127.0.1.1,让机器在没有网络时也能解析自己的名称,返回的正是这一行的内容。请改用大写 I 的形式 hostname -I,它读取真实的网卡地址,或者用 ip -4 addr 查看完整信息。如何查找网络中其他设备的 IP 地址?
ip neigh show 查看(若已安装 net-tools,也可用 arp -a)。若想了解全貌,可对子网做 ping 扫描:nmap -sn 192.168.1.0/24 会列出所有响应的主机,反向 DNS 可用时还会显示名称。请替换成你自己的网络,可从 ip route 中的 scope link 路由读取。在 VPS 上这很少有用,而且扫描相邻地址可能违反服务商的条款。Adrien Roche, 基础设施与主机托管编辑
系统工程师,拥有 10 年以上运维 Windows Server 和 Linux 集群的经验。Adrien 负责 rdp.monster 的基础设施文档,并撰写关于 RDP、VPS 托管、服务器管理、网络和隐私工具的指南。




