我想实现一个 bash 脚本,在我的计算机中的网卡(或接口)名称与其 IP 地址(如果可能的话,采用 CIDR 格式)之间创建映射。
目标是拥有一个类似关联数组的东西,或者一个看起来像这样的文件:
lo: "127.0.0.1/8"
eth0: "192.168.1.123/24"
br-priv: "" # <-- No IP assigned
wlan0: "10.42.0.10/24"
我有ifconfig
和ip
可用命令,但解析它们的输出有点棘手,因为 IP 地址和接口名称没有出现在同一行,所以我必须找到接口 IP 地址,然后回滚才能找到网络名称,反之亦然。
还有其他方法可以找到我的接口 IP 地址吗?
我有下面的所有接口名称(作为目录名称)/sys/class/net/
root@borrajax:~# ls /sys/class/net/
br-priv/ eth0/ lo/ mon0/ wlan0/
但我在这些目录中找不到他们的IP。这样做会很棒,因为我可以遍历目录,检索目录的名称,然后从其他文件中读取 IP。
这是为了在嵌入式系统中运行开放WRT,但基于 Debian 的系统的解决方案可能更合适。我bash
的版本是4.2.28,以防万一。
答案1
使用以下的“-o”选项ip
:
ip -o addr | sed -e 's/^[0-9]: \([^ ]*\).*inet \([^ \t]*\).*/\1: "\2"/;t;s/^[0-9]*: \([^ :]*\).*/\1: ""/g' | sort -r | sort -u -t: -k1,1
输出应该是你的情况:
br-priv: ""
eth0: "192.168.1.123/24"
lo: "127.0.0.1/8"
wlan0: "10.42.0.10/24"
该命令仅打印每个网络设备一个 IPv4(可以在同一接口上配置多个 IP 地址)。
说明:
表达sed
方式
s/^[0-9]: \([^ ]*\).*inet \([^ \t]*\).*/\1: "\2"/;
替换1: lo inet 127.0.0.1/8 brd 255 [...]
为lo: "127.0.0.1/8"
t;
如果可以的话跳转到结尾(=找到 IPv4 地址),否则:
s/^[0-9]*: \([^ :]*\).*/\1: ""/
将没有 IPv4 地址的行替换1: lo inet6 ::1/128 [...]
为lo: ""
.
所有行都会自动打印出来(无-n
标志)。
该命令sort -r
现在对行进行反向排序。在所有情况下,带有 IPv4 地址(例如 )的行都lo: "127.0.0.1/8"
位于不带(lo: ""
)的行之前。
该命令sort -u -t: -k1,1
对第一个字段应用唯一排序(接口名称,分隔符设置为:
)。在我们的示例中,只有 "lo: "127.0.0.1/8"
行因为它排在第一位而得以生存(由于之前的排序)。