本地主机的 IP

Ema*_*erg 6 linux ip

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)

bah*_*mat 7

你的问题有一个根本的缺陷。第一,主机可能(并且很可能会)有一个以上的地址(例如,多个接口),甚至每个接口有一个以上的地址。这对于 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,则每种语言都有自己的方式从内核获取这些数据。我会把这个留给你。

  • 你误会了。您的根本缺陷是您假设每个主机都有一个地址。不是这种情况。但我确实希望这对你有用。 (2认同)

Gil*_*il' 5

信息随时可能发生变化,因此需要从内核中检索,不能存储在文件中。

没有很好的方法来获取这些信息。您的解析与任何解析一样好,除了硬编码第二行是错误的:不能保证接口会以任何特定顺序列出。一台机器有多个接口是很常见的:你可能有多个网卡或虚拟接口。

通常,您感兴趣的 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 变体上,您可能需要调整上面的命令。大多数都有名为ifconfigand 的命令route,但输出格式可能不同。

在 Linux 下,您可以使用iproute2工具套件中的命令代替ifconfigand 。虽然了iproute2的作者认为和被弃用,其实也有一点优势,使用,因为输出是没有明显更容易地剖析,并和始终可用,而一些简装Linux安装省略。routeipifconfigrouteipipifconfigrouteip

  • 我认为`ip`的输出比`ifconfig`更容易解析(但这只是意见)。此外,`ip` 的输出值始终与用于输入的格式相同(使脚本编写非常容易)。然而,`ip` 确实有一个主要的功能,而 `ifconfig` 没有。运行`ip addr add 1.2.3.4/32 dev eth0`(或已经有IP的接口),然后尝试使用`ifconfig`查看该IP。`ifconfig` 不会显示它,而 `ip addr` 会显示。 (3认同)

phe*_*mer 5

这里的所有答案在技术上都是正确的,但它们不是我认为的“正确”答案。不幸的是,您的问题非常含糊(如果您不太了解 Linux 中的网络工作方式,我可以理解这一点),因此我将对问题的可能解释给出一些答案。


机器的主IP

机器有一个高于所有其他 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 与特定目的地通信,请使用以下命令:

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,您可以从默认网关中选择一个。如果您只有一个界面,那么无论如何这都是重要的。
这基本上和上面的完全一样,只是使用默认网关作为我们的目的地来查找

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)