到目前为止,我的网络脚本使用了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