12

我有一个在各种不同的 Ubuntu Linux 机器上运行的 bash 脚本。它的工作是找出本地主机的 LAN IPv4 地址。

该脚本正在使用

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

这很好,但有些机器出于某种原因使用 eth1 而不是 eth0。我希望能够发现 LAN iface 名称,所以我可以在这里替换它而不是 eth0。

当然,如果你能想出一个不同的 oneliner 来做同样的事情,那就太好了。

4

7 回答 7

15

不确定这是否有帮助,但似乎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 脚本中使用类似的东西来自动化它,

ip route get 8.8.8.8 | awk '{ print $NF; exit }'
于 2013-05-09T18:59:32.077 回答
15

主网卡通常会有一个默认路由。所以:

ip -o -4 route show to default

网卡:

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

网关:

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

与 ifconfig 不同,ip 具有一致且可解析的输出。它仅适用于 Linux;它不适用于其他 Unixen。

于 2015-05-12T20:46:50.783 回答
4

最近,systemd/udev 已经自动开始为所有本地以太网、WLAN 和 WWAN 接口分配接口名称,我们都习惯了。这与传统的接口命名方案(“eth0”,“eth1”,“wlan0”,...)有所不同。现在我们必须先检查本地接口名称是什么,然后才能使用它,而之前我们使用它非常准确地猜测“eth0”是正确的名称。您要的是网络名称..这是一个解决问题的小脚本

  1. 使用“ip route get 8.8.8.8”来确定哪个 ACTIVE 接口具有到 Internet 的路由(或当前正在使用)输出应如下所示:

    8.8.4.4 通过 10.10.1.1 开发 enp0s3 src 10.10.1.118 缓存

  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

于 2014-12-01T05:25:45.013 回答
3

信不信由你,没有标准的、简单的方法来获取这些信息。没有标准给我当前的 IP 和接口名称命令。甚至没有标准格式返回的信息ifconfig

我将建议放弃纯 shell 并使用 Python 之类的脚本语言,您可以在其中执行以下操作:

import socket
socket.gethostbyname(socket.gethostname())

除非它在大多数 Linux 系统上不起作用,因为/etc/host文件中通常有一个条目指向127.0.0.1,即环回地址。Perl也有同样的问题。

您牢牢掌握了所涉及的脚本,并且您已经看到了这些问题。我唯一能推荐的是在你要运行它的每台机器上测试它,看看会弹出什么。由于网络的设置方式和接口可能由每个位置命名的方式,不会有一个通用的、适用于所有操作系统的班轮,甚至不会适用于同一操作系统上的不同系统。

于 2013-01-06T20:34:17.717 回答
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 }'
于 2012-09-18T09:58:08.933 回答
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

于 2013-01-06T18:09:06.753 回答
1

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

ip addr show | grep "inet 10.67.5." \
    | sed -n '/inet /{s/^.*inet \([0-9.]\+\).*$/\1/;p}'
于 2012-09-18T09:35:06.303 回答