Linux实例如何确定其IP地址?
也就是说,不是 127.0.0.1。
这是存储在文件中还是 ifconfig 在每次调用时都会以某种方式计算它?
我设法解决它只是为了表明我付出了努力,但这不是我在认真的应用程序中放入的任何内容:
sudo ifconfig | head -n 2 | tail -n 1 | tr -s " " | tr " " ":" | cut -d":" -f 4
答案1
你的问题有一个根本性的缺陷。首先,主机可能(并且很可能)具有多个地址(例如,多个接口),甚至每个接口具有多个地址。对于 IPv6,这更是一个问题,其中每个全球连接的主机至少二地址。
其次,从 shell 执行此操作的“最佳”方法因系统而异。
Linux:
/sbin/ip addr show eth0 | awk -F"[ /]+" '/inet / {print $3}'
>= Solaris 11:
ipadm show-addr net0/v4 | awk -F"[ /]+" '/ok/ {print $5}'
Mac OS X/达尔文:
ipconfig getifaddr en0
即使采用最低公分母并使用ifconfig
也不会保持一致,因为输出格式可能会发生变化。但是,要清理您的示例,请使用以下命令:
ifconfig eth0 | awk -F"[ :]+" '/inet / {print $4}'
如果您使用 perl、ruby、java 等更高级的语言而不是 shell,则每种语言都有自己的从内核获取此数据的方法。我将把这个问题留给你来寻找。
答案2
这些信息随时可能改变,因此需要从内核中检索,不能存储在文件中。
没有真正好的方法来获取此信息。您的解析与任何解析一样好,只是第二行的硬编码是错误的:不能保证接口将以任何特定顺序列出。一台机器具有多个接口是相当常见的:您可能有多个网卡或虚拟接口。
通常,您感兴趣的 IP 地址是与默认路由关联的 IP 地址。对于大多数配置,您可以使用该命令获取正确的接口route
,然后使用 提取该接口的 IP 地址ifconfig
。
/sbin/ifconfig $(/sbin/route -n |
awk '$1 == "0.0.0.0" {print $8}') |
awk 'match($0, /inet addr:[.0-9]+/) {print substr($0, RSTART+10, RLENGTH-10)}'
请注意,无需调用sudo
.ifconfig
并且route
通常不是PATH
非 root 用户的默认设置,但只要您只是读取信息而不更改设置,就可以在没有特殊权限的情况下使用它们。
在 Linux 以外的 UNIX 变体上,您可能需要调整上面的命令。大多数都有名为ifconfig
和的命令route
,但输出格式可能不同。
在 Linux 下,您可以使用以下命令来代替ifconfig
和:route
ip
ip路由2工具套件。虽然 iproute2 的作者考虑ifconfig
并route
弃用 iproute2,但实际上使用 并没有什么优势ip
,因为 的输出ip
并没有明显更容易解析,并且ifconfig
和route
始终可用,而一些精简的 Linux 安装省略了ip
。
答案3
这里的所有答案在技术上都是正确的,但它们不是我认为的“正确”答案。不幸的是,你的问题非常模糊(如果你不太了解 Linux 中的网络工作原理,我可以理解),所以我将对这个问题的可能解释给出一些答案。
机器的主IP
该机器有一个高于所有其他 IP 的 IP,该 IP 被视为机器的主要 IP。请注意,尽管这毫无意义,因为一个盒子可以有多个 IP,并且使用哪个 IP 会有所不同(我稍后会详细介绍这一点)。
主 IP 只是与计算机主机名关联的 IP。您可以通过运行以下命令找到该IP
getent hosts "$(hostname)" | awk '{ print $1 }'
现在,它的作用是根据 查找机器主机名的 IP /etc/nsswitch.conf
。在大多数情况下,该/etc/nsswitch.conf
文件包含hosts: files dns
.这意味着当尝试执行任何类型的主机名或地址查找时,它将/etc/hosts
首先查找,然后查询 DNS(如配置/etc/resolv.conf
)。
因此该命令getent hosts "$(hostname)"
可能会从 中获取匹配的条目/etc/hosts
。只是awk
简单地从该行中获取 IP。
(getent
只是一个用于查询中列出的“数据库”的简单实用程序/etc/nsswitch.conf
)
用于与外界通信的IP
正如我之前提到的,机器的主 IP 毫无意义。机器可以使用多个 IP 中的任何一个进行通信。就您而言,您可能只有一个接口和一个(非本地主机)IP。但是,一台服务器可以有多个接口或 IP(有时单个接口上有多个 IP)。
使用哪个 IP 由内核的路由表决定。我不打算详细介绍路由表的工作原理,因为它并不简单(有多个路由表,使用哪一个取决于表选择规则)。我只是告诉你如何找到哪个IP将被使用。
要找出将使用哪个 IP 与特定目标进行通信,请使用以下命令:
ip route get 1.2.3.4
(作为1.2.3.4
目的地的IP)
在我的机器上,如果我使用 google.com 的 IP ( ) 之一执行此操作74.125.139.102
,我会得到以下结果:
74.125.139.102 via 192.168.0.1 dev wlan0 src 192.168.0.24
cache
这告诉我的是,192.168.0.24
每当我的机器与 . 进行通信时,都会使用该 IP 74.125.139.102
。
如果你只想要IP,你可以grep
在最后添加一个额外的IP。
ip route get 1.2.3.4 | grep -oP '(?<=src )\S+'
grep
使用 代替 an 是awk
因为它不太容易出错。该行可能会发生变化,其中 IP 不会位于同一位置,但它始终遵循“src”,因此我们只需立即获取“src”之后的值
默认网关IP
最后,还有默认网关。如果您没有特定的目的地来查询将使用哪个 IP,则可以从默认网关中选择一个。如果您只有一个界面,那么无论如何这都是最重要的。
这基本上和上面一模一样,只是使用默认网关作为我们查找的目的地
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')"
这将为您提供类似于上一节中的一行。该src
值是将用于流经默认网关的流量的 IP。
与上一节一样,要仅获取 IP,请添加grep
.
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')" | grep -oP '(?<=src )\S+'
答案4
您的请求不明确,通常使用“localhost”一词表示环回接口,而 127.0.0.1 是最常见和正确的答案。
你缺少的是:
- 事实上,每个接口都可以有不同的 IP,环回接口是一个网络接口,就像您的以太网卡或无线 USB 接收器一样。
- 因此,一台 PC 没有一个 IP,这完全取决于您正在考虑的接口以及您的操作系统下使用的接口数量。
您可能对“内核路由表”主题感兴趣,这是开始了解内核如何处理网络活动的好方法。