我制作了一个在服务器上运行的 Bash 工具。该工具将在特定时间范围(即上午 5 点到下午 3:30)内阻止某些 IP 地址。
截至目前,该工具工作正常,但我必须手动将某些网站的 IP 地址输入到文本文件中,并让该工具使用“head”和“tail”命令根据第 n 行提取 IP 地址。我不想这样做,因为我相信单个 ping 会更加轻便和便携。因此,如果我对 Google 进行 ping 操作:
ping google.com -c 1 -s 16
输出将是:
Ubuntu@yokai:~# ping google.com -c 1 -s 16
PING google.com (173.194.66.138) 16(44) bytes of data.
24 bytes from qo-in-f138.1e100.net (173.194.66.138): icmp_seq=1 ttl=37 time=46.7 ms
--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 46.748/46.748/46.748/0.000 ms
我缩小输出范围的命令是:
ping google.com -c 1 -s 16 | grep -o '([^ ]*' | tr -d '(44):\n'
这给了我一个输出:
173.19.66.113173.19.66.113ubuntu@yokai
如您所见,同一 IP 地址有重复。如何使用 sed 删除重复项,以便可以将单个 IP 地址存储到变量中并将脚本作为 cronjob 运行,或者我是否可以使用 tr 更好地跟踪?
(编辑)
我已经知道如何从主机名或域解析 IP 地址。我在这里问的不是这个。这个问题具体是关于使用 sed 管理 ping 输出,以便使我创建的工具更具可移植性,因为 ping 几乎是所有 Linux 发行版的默认设置。
(更新)由于有些人将这个问题标记为与其他一些与此无关的废话问题的重复项,我会说得足够清楚,让英语理解困难的迟钝者可以理解:
如何解析这“仅”IP 地址从ping
输出ping
在域名上使用时。
这不是要求解析域名,因此不是重复!
(最新更新)自从问这个问题以来,我已经学会了正确的 POSIX 正则表达式来完成我需要的事情,我需要明确的是,我最初是在询问正则表达式,以便sed
从 ping 输出打印单个 IP 实例。此后,我改进了我的方法,不再使用此处的任何答案,但我感谢每个人在此提供帮助的尝试。我现在使用我创建的计时器脚本来在某些时间配置 iptables 以阻止某些域名解析。再次感谢所有试图提供帮助的人。
答案1
ping
用于根据 ICMP 响应检查主机是否启动或关闭,它绝不是仅解析 IP 地址的正确工具,有专门的工具用于此目的。
你应该看看dig
,,host
——nslookup
无论什么最适合你。
这是一个dig
输出:
% dig +short google.com
123.108.243.57
123.108.243.51
123.108.243.54
123.108.243.48
123.108.243.60
123.108.243.52
123.108.243.56
123.108.243.55
123.108.243.61
123.108.243.58
123.108.243.49
123.108.243.50
123.108.243.59
123.108.243.47
123.108.243.53
附带说明一下,在 Linux 中,如果您想通过 NSSwitch(名称服务交换机)即进行查询/etc/nsswitch
,请使用getent
带有hosts
(或ahosts
)数据库的命令,例如:
getent hosts google.com
在我的电脑中,我有:
hosts: files mdns4 dns
中/etc/nsswitch.conf
,因此getent hosts
将按顺序查询并使用gethostbyaddr(3)
或gethostbyname(3)
基于名称并ahosts
使用getaddrinfo(3)
。
本质上,根据我的配置,这将首先检查/etc/hosts
,然后是 mDNS,最后是 DNS。
如果你坚持使用ping
and sed
,你可以这样做:
% ping -c1 google.com | sed -nE 's/^PING[^(]+\(([^)]+)\).*/\1/p'
123.108.243.56
答案2
浏览 Google 我发现了另一个链接unix.SE 帖子提到getent
- 我什至不知道这个程序的存在。
您可以使用getent
likedig
将 IP 解析为主机名 - 我的系统已getent
默认安装,但没有dig
。如果您需要 ipv6 主机,请更改ahostsv4
为ahostsv6
.
getent ahostsv4 google.com | awk '{print $1}' | head -1
我添加这个答案是因为我不擅长正则表达式/sed,并且无法想出@heemayl 的答案。
答案3
需要注意的一件事是,正如您在 @heemayl 的dig
输出中看到的那样,某些站点可能有多个 IP 地址。您可能需要进行 DNS 查找才能获取所有这些地址,因为ping
只使用它获取的第一个地址。对于其他主要想要连接的东西也是如此,而不是具体列出地址。
(此外,对于像 google 这样的情况,您将获得不同的 IP 地址,具体取决于您所在的位置。这里可能不是问题,但值得注意。)
另一件事,关于你使用的命令。此操作:从输入中tr -d '(44):\n'
删除字符(
、4
、)
、:
和的所有副本。始终只查看单个字符,而不是字符串。查看获得的输出,您会发现IP 地址中间缺少 a。使用其他一些工具,例如处理字符串。\n
tr
4
sed
只是为了显示不同的颜色自行车棚,这是另一个简单的,使用 GNU grep:
$ ping google.com -c1 | head -1 | grep -Eo '[0-9.]{4,}'
172.217.22.174