Linux 实例如何确定自己的 IP 地址?
也就是说,不是 127.0.0.1。
这是存储在文件中还是 ifconfig 在每次调用时以某种方式计算它?
我设法解决了它,只是为了表明我付出了努力,但这并不是我在认真的申请中投入的任何东西:
sudo ifconfig | head -n 2 | tail -n 1 | tr -s " " | tr " " ":" | cut -d":" -f 4
Run Code Online (Sandbox Code Playgroud)
你的问题有一个根本的缺陷。第一,主机可能(并且很可能会)有一个以上的地址(例如,多个接口),甚至每个接口有一个以上的地址。这对于 IPv6 来说更是一个问题,其中每个全局连接的主机至少有两个地址。
其次,从 shell 执行此操作的“最佳”方法因系统而异。
Linux:
/sbin/ip addr show eth0 | awk -F"[ /]+" '/inet / {print $3}'
Run Code Online (Sandbox Code Playgroud)
>= Solaris 11:
ipadm show-addr net0/v4 | awk -F"[ /]+" '/ok/ {print $5}'
Run Code Online (Sandbox Code Playgroud)
Mac OS X/达尔文:
ipconfig getifaddr en0
Run Code Online (Sandbox Code Playgroud)
即使使用最低公分母和使用ifconfig
也不会一致,因为输出格式可能会改变。但是,要清理您的示例,请使用以下命令:
ifconfig eth0 | awk -F"[ :]+" '/inet / {print $4}'
Run Code Online (Sandbox Code Playgroud)
如果您使用更高级的语言,如 perl、ruby、java 等,而不是 shell,则每种语言都有自己的方式从内核获取这些数据。我会把这个留给你。
信息随时可能发生变化,因此需要从内核中检索,不能存储在文件中。
没有很好的方法来获取这些信息。您的解析与任何解析一样好,除了硬编码第二行是错误的:不能保证接口会以任何特定顺序列出。一台机器有多个接口是很常见的:你可能有多个网卡或虚拟接口。
通常,您感兴趣的 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)}'
Run Code Online (Sandbox Code Playgroud)
请注意,无需调用sudo
. ifconfig
并且route
通常不是PATH
非 root 用户的默认设置,但是只要您只是阅读信息而不更改设置,您就可以在没有特殊权限的情况下使用它们。
在 Linux 以外的 unix 变体上,您可能需要调整上面的命令。大多数都有名为ifconfig
and 的命令route
,但输出格式可能不同。
在 Linux 下,您可以使用iproute2工具套件中的命令代替ifconfig
and 。虽然了iproute2的作者认为和被弃用,其实也有一点优势,使用,因为输出是没有明显更容易地剖析,并和始终可用,而一些简装Linux安装省略。route
ip
ifconfig
route
ip
ip
ifconfig
route
ip
这里的所有答案在技术上都是正确的,但它们不是我认为的“正确”答案。不幸的是,您的问题非常含糊(如果您不太了解 Linux 中的网络工作方式,我可以理解这一点),因此我将对问题的可能解释给出一些答案。
机器有一个高于所有其他 IP 的 IP,这被认为是机器的主要 IP。请注意,虽然这非常没有意义,因为一个盒子可以有多个 IP,使用的 IP 各不相同(我稍后会详细介绍)。
主 IP 只是与机器主机名关联的 IP。您可以通过运行以下命令找到此 IP
getent hosts "$(hostname)" | awk '{ print $1 }'
Run Code Online (Sandbox Code Playgroud)
现在,它的作用是根据/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 route get 1.2.3.4
Run Code Online (Sandbox Code Playgroud)
(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
Run Code Online (Sandbox Code Playgroud)
这告诉我的是,192.168.0.24
每当我的机器与74.125.139.102
.
如果你只想要 IP,你可以grep
在最后添加一个额外的。
ip route get 1.2.3.4 | grep -oP '(?<=src )\S+'
Run Code Online (Sandbox Code Playgroud)
grep
被用来代替 awk
因为它不太容易出错。行可能会改变,其中 IP 不会在同一个地方,但它会始终跟在“src”之后,所以我们只需在“src”之后立即获取值
最后,还有默认网关。如果您没有要查询的特定目的地以查看将使用哪个 IP,您可以从默认网关中选择一个。如果您只有一个界面,那么无论如何这都是重要的。
这基本上和上面的完全一样,只是使用默认网关作为我们的目的地来查找
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')"
Run Code Online (Sandbox Code Playgroud)
这将为您提供一条类似于上一节中的行。这src
值是将用于流经默认网关的流量的 IP。
与上一节一样,要仅获取 IP,请添加grep
.
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')" | grep -oP '(?<=src )\S+'
Run Code Online (Sandbox Code Playgroud)