在 Arch Linux 上获取本地 IP 地址

在 Arch Linux 上获取本地 IP 地址

到目前为止,我的网络脚本使用了hostname -i,但是在最近的更新后,该命令开始抛出错误:hostname: gethostbyname: Unknown host

现在我不知道...我应该研究一个像这样的新命令吗ip?或者这是一个常见问题?我似乎找不到任何地方提到它。我会使用ip,但我找不到一种方法来同时显示两个 IP。例如,当我的两个接口都已连接时(eth 和 wlp)。

有什么建议么?

答案1

今天我也遇到了同样的事情。我检查/校验了 /usr/bin/hostname 文件最近没有更改。

我 grep 了打开文件的 strace 输出(不包括备用 $PATH 中的“没有这样的文件”):

$ strace hostname -i |& grep open | grep -v "No such file"
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 3
open("/usr/lib/libnss_mymachines.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libnss_resolve.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4

逐一检查并与前几天的增量备份进行比较发现,/etc/nsswitch.conf 与 2015 年 9 月 30 日的版本相比在 2016 年 12 月 10 日发生了变化。

并排差异显示差异(左侧为先前的和已恢复的,右侧为最新的和已备份的):

$ diff -y /etc/nsswitch.conf /etc/nsswitch.conf.bck | grep \|
passwd: files                                                 | passwd: compat mymachines systemd
group: files                                                  | group: compat mymachines systemd
shadow: files                                                 | shadow: compat
hosts: files dns myhostname                                   | hosts: files mymachines resolve [!UNAVAIL=return] dns myhostn

恢复以前的 /etc/nsswitch.conf 可以解决问题,“hostname -i”会照常返回接口给出的 IP。您应该备份最新的 IP 以防万一。

更新:在我提交的错误之后(https://bugs.archlinux.org/task/52133),systemd 软件包维护者 Dave Reisner 指出,只有当系统解析的守护进程不工作时,才会出现此问题。我检查了一下,这是正确的。为了让新的 /etc/nsswitch.conf 正常工作:

systemctl enable systemd-resolved

是需要的。

根据“顶部”输出,这将增加约 4m 的常驻大小。或者,您可以继续执行上一行,而不使用 systemd-resolved。

答案2

如果您打算使用ip,这是一个如何从此ip address show输出中获取正确 IP 地址的示例:

$ ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:92:55:ff brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 192.168.124.29/24 metric 1024 brd 192.168.124.255 scope global dynamic eth0
       valid_lft 2742sec preferred_lft 2742sec
    inet6 fe80::5054:ff:fe92:55ff/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

跑步:

ip a s dev eth0 | grep "inet " | grep -oE "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" | head -1


解释:

  • ip a s dev eth0,与 相同ip address show dev eth0,将仅输出有关设备 的信息eth0。这是我需要的具有 IP 地址的设备。输出为:
$ ip a s dev eth0

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:92:55:ff brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 192.168.124.29/24 metric 1024 brd 192.168.124.255 scope global dynamic eth0
       valid_lft 2331sec preferred_lft 2331sec
    inet6 fe80::5054:ff:fe92:55ff/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

  • grep "inet "将匹配包含 的行inet。空格对于避免匹配非常重要inet6(您也可以运行ip -4 a s dev eth0)。输出:
$ ip a s dev eth0 | grep "inet "

    inet 192.168.124.29/24 metric 1024 brd 192.168.124.255 scope global dynamic eth0

  • grep -oE "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}"是一个匹配的正则表达式仅有的具有以下特征的字符串:“(1 至 3 位数字)DOT(1 至 3 位数字)DOT(1 至 3 位数字)DOT(1 至 3 位数字)”.
    正则表达式模式也可以存储在变量中并在稍后使用:
    REGEX="[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}",输出:
$ REGEX="[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}"
$ ip a s dev eth0 | grep "inet " | grep -oE $REGEX

192.168.124.29
192.168.124.255

  • head -1只输出第一个匹配项(第一行),也就是紧接着的那个init(第二个是broadcast地址)。输出:
$ REGEX="[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}"
$ ip a s dev eth0 | grep "inet " | grep -oE $REGEX | head -1

192.168.124.29


如果您有权访问hostname -I,请使用以下命令:

hostname -I | cut -d' ' -f1

相关内容