为什么这个命令失败(这是实际命令的简化版本)?
/tmp $ echo 74.6.231.20 | xargs -n1 -I {} echo "$(host -d {})"
Trying "74.6.231.20.<REDACTED>.<REDACTED>.com"
Trying "74.6.231.20"
Host 74.6.231.20 not found: 3(NXDOMAIN)
Received 95 bytes from 10.163.24.1#53 in 1 ms
这主持人命令将 74.6.231.20 视为主机名而不是 IP 地址,这就是它失败的原因(即没有 74.6.231.20 主机名/FQDN)。
直接指定IP地址即可:
/tmp $ echo 216.58.195.78 | xargs -n1 -I {} echo "$(host -d 216.58.195.78)"
Trying "78.195.58.216.in-addr.arpa"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21425
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;78.195.58.216.in-addr.arpa. IN PTR
;; ANSWER SECTION:
78.195.58.216.in-addr.arpa. 85730 IN PTR sfo07s16-in-f78.1e100.net.
78.195.58.216.in-addr.arpa. 85730 IN PTR sfo07s16-in-f14.1e100.net.
Received 113 bytes from 10.163.24.1#53 in 2 ms
消除回声命令也有效:
/tmp echo 74.6.231.20 | xargs -n1 -I {} sh -c "(host {})"
20.231.6.74.in-addr.arpa domain name pointer media-router-fp73.prod.media.vip.ne1.yahoo.com.
问题似乎是 xargs 与 echo 的组合以及 xargs 如何进行 {} 字符串替换。
ps 我知道有解决方法,我主要感兴趣的是找到阻止此命令成功运行的已损坏的交互。谢谢。
答案1
发生这种情况是因为您的 shell 在将命令行参数作为参数传递给命令之前先对命令行参数执行变量和命令替换,因此这种情况$(host -d {})
发生在xargs
.第二个echo
命令实际上输出:
Trying "{}.<REDACTED>.<REDACTED>.com"
Trying "{}"
Host {} not found: 3(NXDOMAIN)
Received 95 bytes from 10.163.24.1#53 in 1 ms
然后将输出xargs
替换为 IP 地址,使其看起来像是命令发生故障。您可以在运行管道之前使用以下命令亲自查看:{}
host
set -x
( set -x; echo 74.6.231.20 | xargs -n1 -I {} echo "$(host -d {})" )
+ echo 74.6.231.20
++ host -d '{}'
+ xargs -n1 -I '{}' echo 'Trying "{}.<REDACTED>.<REDACTED>.com"
Trying "{}"
Host {} not found: 3(NXDOMAIN)
Received 95 bytes from 10.163.24.1#53 in 1 ms'
Trying "74.6.231.20.<REDACTED>.<REDACTED>.com"
Trying "74.6.231.20"
Host 74.6.231.20 not found: 3(NXDOMAIN)
Received 95 bytes from 10.163.24.1#53 in 1 ms
在此特定示例中,如果您只想显示 的输出host
,则无需捕获它然后显式显示echo
它。只需这样做就足够了:
echo 74.6.231.20 | xargs -n1 host -d
编辑:
xargs
下面是如何将输入传递给多个命令的示例。这是有效的,因为bash
会将命令后面的任何参数分配-c
为位置参数,以$0
.
echo 74.6.231.20 | xargs -n1 -I '{}' /bin/bash -c 'echo "$0"; host -d "$0"' '{}'