我对网络层没有太多了解,我知道获取 IP 地址的基本命令。
有一个要求,我需要读取 IP 地址,它应该适用于任何 Linux 或 Unix 系统。
我正在尝试使用以下命令获取 IP 地址。
ip route get 1.2.3.4 | grep -Po -- 'src \K\S*'.
对于某些系统,我能够获取系统 IP 地址 IPV4/IPV6。
但对于一些我收到一个错误: RTNETLINK 回答:网络无法接通。
我尝试了其他 ip route 命令,但出现同样的错误。
如何读取可在任何 Linux/Unix 系统上使用的 IP 地址。
答案1
不存在适用于所有 Linux / Unix 变体的单一命令。
例如基于 FreeBSD 的系统使用ifconfig
。
早期的 Linux 使用了ifconfig
. ,ip
后来被添加作为替代,但不能相信它在所有发行版中都可用。
首先,您需要更准确地定义您想要支持什么系统。
- 它仅限于基于 Linux 的发行版吗?
- 哪些(RedHat、CentOS、Fedora、Debian 还是 Ubuntu?)?
- 您需要支持每个发行版的多少旧版本?
- 您是否想支持其他 Unix 变体(FreeBSD、OpenBSD、Solaris 等)?
- 有哪些?有多旧?
那么你有两种可能性:
使用额外的软件包。它实现了一个抽象,您可以使用统一的命令获取信息。然后软件内部使用特定于操作系统的方法来获取信息。您需要检查额外的软件包是否支持您的所有要求。
自己实现抽象来支持所需的操作系统。
这里没有简单的答案,您需要自己进行研究来找到/实施执行任务的工具。找到工具后,您可以在此处询问有关使用该工具的具体问题。
答案2
我更喜欢hostname
使用ip
基于 GNU/LINUX Debian 的发行版
过去我使用过ifconfig
,但现在已被替换,ip
并且不再适用于基于 GNU/LINUX Debian 的发行版的最基本安装,你必须通过net-tools
检查手册页hostname
和ip
就像 @Tero Kilkanen 写的那样
这里没有简单的答案,您需要做自己的研究来找到/实施执行任务的工具。
- 检查您需要的工具
- 满足您的需要的命令
- 编写一个脚本来帮你找到解决方案
全IP
hostname -I
hostname -I | tr " " "\n"
全部 IPv4
hostname -I | grep -Eo '([0-9]*\.){3}[0-9]*' | tr '\n' '\n'
全部 IPv6
hostname -I | grep -Eo '([a-z0-9]*\:){7}[a-z0-9]*' | tr '\n' '\n'
所有 IP 对象
ip a
所有 inet ip
ip a | grep inet
所有 ip(lo/ipv4/ipv6) 带网络掩码
ip a | grep inet | cut -d' ' -f6
所有 ip(lo/ipv4/ipv6) 没有网络掩码
ip a | grep inet | cut -d' ' -f6 | cut -d'/' -f1
如果你需要有关您的网络设备的更多信息也检查一下这个帖子
答案3
使用curl
,我会使用ipinfo.io
$ curl -s ipinfo.io | grep -Po 'ip[^0-9]*"\K[^"]*'
12.34.56.78
或者
$ curl -s ipinfo.io | sed -En '/ip/s/[^0-9]*"([^"]*).*/\1/p'
12.34.56.78
这应该适用于几乎每个系统。
答案4
简单的:
ip addr
将返回所有网络接口的 ipv4 和 ipv6 地址。
要获取 ipv4,仅使用-4
。
喜欢ip -4 addr
。
要获取 IPv6,您只需要使用-6
。
喜欢:ip -6 addr
。
要获取 1 个接口的 IPv4 地址,请eth0
使用以下命令:
ip -4 addr show dev eth0
如果您只想获取 ipv4 地址,那么您肯定必须使用某种脚本。
但是假设你运行上面的 ip 命令。这将在我的 Ubuntu WSL 中产生以下内容:
6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 172.26.105.98/20 brd 172.26.111.255 scope global eth0
valid_lft forever preferred_lft forever
获取 ip 地址的一种快速而简单的方法是调用上述命令,将其存储在一个变量中,并且每当有空格字符(空格、换行符、制表符等)时将文本拆分为一个数组。
当由于相邻的多个空格字符而导致空元素被删除时,上述文本将生成一个包含 24 个元素的数组。
打印数组中的第 15 个元素将返回172.26.105.98/20
,如果您使用/
分隔符拆分该元素,则会得到172.26.105.98
。
当然还有其他方法可以做到这一点,通过使用 perl、python 或任何你喜欢的语言,这只是一个粗糙的版本。
目前我正在深入研究使用正则表达式从上面的输出中获取地址。
更新 2:
使用正则表达式进行更多操作,我并不特别感兴趣检查 ip 地址是否是有效的 ip 地址,因为我们知道它是有效的,所以给了我以下命令。
使用上面的输出作为命令的基础:
ip -4 addr show dev eth0 | egrep -o 'inet(.*)(brd|scope)' | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'
这将给出输出:
172.26.105.98
简短解释一下(以防人们不读评论)。
首先,我们将所有内容从ip addr
传输到 egrep 并显示 和 之间的所有内容inet
,或者和brd
之间的替代方案。inet
scope
这就是命令:egrep -o 'inet(.*)(brd|scope)'
为我们做。
这给了我们:
inet 172.26.105.98/20 brd
第二次通过 egrep 时我们只对 ip 感兴趣。
此事由以下人员处理:
egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'
这样我们就只剩下 ipv4 地址了。
从这里你可以创建一个 shell 脚本,以随机设备作为输入并提供 ipv4 地址:
getip.sh
例如创建一个包含以下内容的文件名:
#!/bin/bash
# Call the script with the first agument being the device
DEVICE=$1
ip -4 addr show dev $DEVICE | egrep -o 'inet(.*)(brd|scope)' | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}'
然后您可以使用该命令调用该脚本getip.sh eth0
,它将仅返回 IP 地址。
使用我的 Ubuntu for WSL 的几个示例:
getip.sh lo
给出127.0.0.1
getip.sh eth0
给出172.26.105.98
对 ipv6 地址执行相同操作会稍微复杂一些,因为 ipv6 的正则表达式更长……
希望这能回答你的问题?