![如何使 xargs ping 和 head 输出符合预期?](https://linux22.com/image/38783/%E5%A6%82%E4%BD%95%E4%BD%BF%20xargs%20ping%20%E5%92%8C%20head%20%E8%BE%93%E5%87%BA%E7%AC%A6%E5%90%88%E9%A2%84%E6%9C%9F%EF%BC%9F.png)
给定一组域,我想获取它们的 IP 地址,格式如下:
98.139.183.24
98.137.236.24
这个脚本
#!/bin/bash
domains=(yahoo.com yahoo.ca)
printf "%s\0" "${domains[@]}" | xargs -0 -t -n 1 ping -c 1 -w 3 | grep -E 'PING.*' | sed -r 's:^.*\((([0-9]{1,3}\.){3}[0-9]{1,3})\).*$:\1:'
给出预期的输出。但最初我尝试了:
printf "%s\0" "${domains[@]}" | xargs -0 -t -n 1 ping -c 1 -w 3 | head -n 1 | sed -r 's:^.*\((([0-9]{1,3}\.){3}[0-9]{1,3})\).*$:\1:'
并且命令以信号 13 退出(根据我的理解,这意味着管道损坏?!?)。显然问题出在head
.现在我想探讨为什么它不起作用,以及我是否以及最终如何使这个长“wiener”与head
.我还没有尝试过,但我很确定它可以使用for
构造并使用head
for every 来工作ping
。xargs
与该选项一起使用-P
也不起作用。我想主要问题是head
将输出作为一个连续文件提供xargs
(我说得对还是“输入”?)。
EDIT1:我的目标是获取一组网站地址的 IP 地址,然后通过使用whois
和管道输出来检查这些 IP 也注册到哪些组织sed
,然后可能进行一些分组,这样我只有唯一的名称,没有重复。我同意dig
或host
比这一点更彻底,ping
但我相当确定这些网站足够小,每个域只能找到一个 IP 地址。尽管如此,我想现在我会按照其他人的建议去做dig
(或者host
;我还没有决定)。
为了弄清楚为什么我对使用感兴趣head
而不是grep
为了我需要的东西:我只是好奇它会如何完成(我对 bash 和 Linux 总体来说很陌生)并且我觉得它可能会澄清管道的工作原理。就这样
答案1
head -n 1
在打印第一行后退出,并向 writer ( xargs
) 发送 SIGPIPE 来表明没有进程可以读取它所写入的内容。作为响应,xargs
执行大多数进程执行的操作并终止其子进程 ( ping
),打印警告,可能将 SIGPIPE 发送到其自己的父进程,然后终止自身。
但是,您会注意到,由于您尚未pipefail
在脚本中设置,因此完整脚本的退出代码为零 -sed
命令的退出代码。
答案2
echo 192.168.1.1 192.168.1.2 192.168.1.3|xargs -n1 ping -w 1
或使用 grep,仅查看非 ping 节点
echo 192.168.1.1 192.168.1.2 192.168.1.3|xargs -n1 ping -w 1|grep -b1 100