我有一个 bash 脚本,我想获取给定网络适配器(在我的情况下为“ens18”)的全局 IPv6 地址。首先,我发出了以下命令:

ip -6 addr

这给了我以下输出,其中包含我正在寻找的地址:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fd00::3170:4ff:eff4:a4ab/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 6736sec preferred_lft 3136sec
    inet6 2a02:8070:2982:4300:3170:4ff:eff4:a4ab/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 6736sec preferred_lft 3136sec
    inet6 af60::3170:4ff:eff4:a4ab/64 scope link 
       valid_lft forever preferred_lft forever
3: br-7ac197bd041e: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP 
    inet6 af60::42:80ff:fe52:3481/64 scope link 
       valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP 
    inet6 af60::42:6eff:fecf:5e6/64 scope link 
       valid_lft forever preferred_lft forever
6: veth074f8b0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP 
    inet6 af60::7073:40ff:fe59:aad0/64 scope link 
       valid_lft forever preferred_lft forever
8: vethe85ed67@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP 
    inet6 af60::5c09:65ff:fe34:34f4/64 scope link 
       valid_lft forever preferred_lft forever

因此全局 IPv6 地址为“2a02:8070:2982:4300:3170:4ff:eff4:a4ab”。

如何从我的 bash 脚本中可靠地检索该值?


最佳答案
2

我会先

ip -6 addr ls dev ens18 scope global | awk '/inet6/ && $2 !~ /^f/ {print $2}'

在哪里

  • dev ens18告诉ip仅查询ens18
  • /inet6/ && $2 !~ /^f/告诉 awk 过滤 ipv6,ip 不以f
  • { print $2}打印值

请注意,ipv6 类似于fe80::fd00::和站点地址。


更二十一世纪的将使用

ip --json addr |
  jq -r '.[].addr_info[] |
         select(.scope == "global") |
         select(.family == "inet6") |
         .local'

1

  • 感谢@GeraldSchneider 提供 XXI 世纪的方法,我将其折叠起来以便于阅读。


    – 

我想说的是,您无需解析ip输出或依赖类似js(需要安装)的工具,而是可以从输出开始,hostname -I输出仅显示分配给机器的所有 IP 地址的列表。像这样:

for i in `hostname -I`; do if echo ${i} | grep -qv \\. ; then echo ${i}; break; fi done

这将显示列表中出现的第一个 IPv6 地址,即使它是链路本地或站点本地。您也可以通过 grep 查找它们:

for i in `hostname -I`; do if echo ${i} | grep -qvP "\.|^fe80:|^fd00:" ; then echo ${i}; break; fi done

1

  • 同时,这依赖于 Debian 版本hostname– inetutils 版本中没有-I其他一些发行版使用的选项。(它有,-i但只能解析系统主机名,可以将其设置为仅解析为 127.0.0.1。)


    –