如何查找网络接口名称

15
我有一个在不同Ubuntu Linux机器上运行的Bash脚本。它的任务是查找本地主机的LAN IPv4地址。
该脚本使用:
ip addr show eth0 | sed -n '/inet /{s/^.*inet \([0-9.]\+\).*$/\1/;p}'

这是可以的,但由于某些原因,一些机器使用eth1而不是eth0。我想要能够发现局域网接口名称,以便在此处替换eth0。

当然,如果您能想出一个不同的一行代码来完成相同的操作,那也很好。


你应该使用SNMP来完成这个任务,而不是编写脚本。 - Piotr Wadas
@Flexo 啊,我只关心ipv4局域网。已经澄清问题了。 - artfulrobot
ip l |grep <ip> |awk '{print $NF}'ip l |grep <ip> |awk '{print $NF}' - levinit
显示最活跃的以太网接口:arp -n -H ether | perl -ne 'print $1 if /(\S+\n)$/' | sort | uniq -c | grep -v Iface | sort -n | tail -1 | perl -pe 's/.* //' - Erik Aronesty
7个回答

23

主要的网络接口通常会有一个默认路由。因此:

ip -o -4 route show to default
网络接口控制器(NIC):
ip -o -4 route show to default | awk '{print $5}'

网关:

ip -o -4 route show to default | awk '{print $3}'

与ifconfig不同,ip命令具有一致且可解析的输出。 它只能在Linux系统上运行;无法在其他Unix系统上运行。


14

我不确定这是否有帮助,但似乎 ip route get 命令可以显示连接到远程主机所使用的接口。

ubuntu@ip-10-40-24-21:/nail/srv/elasticsearch$ ip route get 8.8.8.8
8.8.8.8 via <gateway address> dev eth0  src <eth0 IP Address>

当然,您可以在Shell脚本中使用类似下面的内容自动化执行:

当然,你可以用类似的Shell脚本实现自动化:

ip route get 8.8.8.8 | awk '{ print $NF; exit }'

1
在我的Ubuntu 15.10机器上,似乎显示的是IP地址而不是接口名称。@user150471下面的答案有效:https://dev59.com/qmcs5IYBdhLWcg3w7IM9#30201105 - rubo77
ip route get 8.8.8.8 | sed -nr 's/.*dev ([^\ ]+).*/\1/p' - h0tw1r3
非常好!我喜欢这个答案,因为它在不同的情况下都非常通用。你只需要知道目标地的IP地址;ip route会自动处理剩下的事情。 - user5395338

5
最近,systemd/udev自动为所有本地以太网、WLAN和WWAN接口分配接口名称,我们都已习惯。这是一种从传统接口命名方案(“eth0”,“eth1”,“wlan0”等)中脱离出来的新命名方式。现在我们必须先检查本地接口名称才能使用它,而之前我们可以相当准确地猜测“eth0”是正确的名字。你需要的是网络名称。下面是一个解决问题的小脚本:
  1. 使用“ip route get 8.8.8.8”来确定哪个活动接口可以访问互联网(或当前正在使用) 输出应该像这样:

    8.8.4.4 via 10.10.1.1 dev enp0s3 src 10.10.1.118 cache

  2. 使用awk打印第5个文本块以获取接口名称

    ]# ip route get 8.8.8.8 | awk -- '{print $5}' 输出:enp0s3

  3. 使用awk打印第7个文本块以获取接口地址

    ]# ip route get 8.8.8.8 | awk -- '{print $7}' 输出:10.10.1.118


很好的答案。我发现ip命令输出两行(第二行是“cache and ipid 0x2e6e”)。所以对我来说,ip route get 8.8.8.8 | head -n1 | awk -- '{print $7}' 是有效的! - artfulrobot

3
相信或不相信,获取这些信息没有标准、简单的方法。没有标准的“给我当前IP和接口名称”的命令。甚至连由ifconfig返回的信息格式都没有标准。
我本来想建议放弃纯shell,使用像Python这样的脚本语言,你可以这样做:
import socket
socket.gethostbyname(socket.gethostname())

除非在/etc/host文件中有指向回环地址127.0.0.1的条目,否则它在大多数Linux系统上无法使用。同样的问题也存在于Perl中。
你对所涉及的脚本有很好的掌握,并且已经看到了其中的问题。我唯一能建议的就是在你要运行它的每台机器上进行测试,看看会出现什么情况。因为网络配置和不同位置可能会命名接口的方式不同,所以不会有一个适用于所有操作系统甚至在同一个操作系统上适用于不同系统的通用一行代码。

当主机名没有DNS或/etc/hosts条目时,它也无法工作。 - gatoatigrado

3

您可以尝试搜索字符串inetbrd(表示广播)以获取以下结果:

ip addr show|egrep '^ *inet'|grep brd|awk -- '{ print $2; }'|sed -e 's:/[0-9]*$::'

请注意,我使用的命令比必要的多;你可能可以用sed和更复杂的正则表达式实现相同的功能,但我更喜欢一个命令,以便通过哪些步骤我得到结果是显而易见的。
如果您想在单个命令中运行它,请尝试使用awk。
ip addr show|awk -- '$1 == "inet" && $3 == "brd"  { split($2,a,"/"); print a[1]; }'

这个版本比使用sed稍微长一点,但更易读。

+1 更易读:

ip addr show | awk '$1 == "inet" && $3 == "brd" { sub (/\/.*/,""); print $2 }'

1

1)这个只打印接口名称(我需要它来处理即将到来和下降的PPP链接):

for i in $( ifconfig | grep 'ppp' | awk '{print $1}' );
do

printf "$i "; ## Or echo

done

结果:

ppp0 ppp1 ppp2

2) 这个打印接口名称和IP地址。

declare -a IPADDR

index=0

for i in $( ifconfig | grep 'inet addr' | awk '{print $2}'| sed 's#addr:##g' );
do
        IPADDR[$index]=$i
        let "index += 1"
done

index=0

for i in $( ifconfig | grep 'ppp' | awk '{print $1}' );
do
        echo $i 
        let "index += 1"
done

结果:

ppp0 地址:IP

ppp1 地址:IP

ppp2 地址:IP


1

我仍然想知道是否有更简单的方法来做到这一点,但这是我的解决方法:我知道局域网子网,所以...

ip addr show | grep "inet 10.67.5." \
    | sed -n '/inet /{s/^.*inet \([0-9.]\+\).*$/\1/;p}'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接