blacklist_ips='
5.56.148.140
94.73.159.66
69.134.15.72
107.150.42.226
195.159.233.44
89.19.7.58
'
for ipx in $blacklist_ips
do
country=`whois $ipx | grep -i country | tail -1 | awk '{print $2}'`
hostx=`host $ipx |awk '{print $NF}'|sed "s/\.$//"`
printf '%s %s %s' $country $ipx $hostx
printf '\n'
done
Run Code Online (Sandbox Code Playgroud)
脚本适用于所有 IP,但对于69.134.15.72
,
country=`whois $ipx | grep -i country | tail -1 | awk '{print $2}'`
Run Code Online (Sandbox Code Playgroud)
结果如下:
connect: Connection refused
Run Code Online (Sandbox Code Playgroud)
这是因为
whois 69.134.15.72
Run Code Online (Sandbox Code Playgroud)
似乎69.134.15.72
没有正确响应。
我不明白为什么它停在第 1 行country
并且脚本执行没有到达下一行。
如何检测connection refused
错误并做出正确反应?
您可以通过使用 if 语句并echo $?
测试最后一个命令的退出状态来执行此操作。数字 0 通常对应于成功。故障可以用一系列数字表示,具体取决于程序。
在这里,whois 69.134.15.72; echo $?
由于Connection Refused
消息而产生 2 。
为接受连接的不同 IP 地址运行命令将产生 0。例如:
$ whois 5.56.148.140 >/dev/null; echo $?
0
Run Code Online (Sandbox Code Playgroud)
在该命令中,我将输出重定向到 /dev/null 以避免混乱。此外,本文中来自这些 IP 地址的此命令的成功或失败将来可能会发生变化。
在您的代码中,您可以首先测试whois
特定 IP 地址的命令,然后仅在退出状态为 0 时运行 for 语句的其余部分。
就像是:
for ipx in $blacklist_ips
do
whois_test=`whois $ipx 2>/dev/null`
ret=$?
if [ $ret -eq 0 ]; then
country=`echo "$whois_test" | grep -i country | tail -1 | awk '{print $2}'`
hostx=`host $ipx |awk '{print $NF}'|sed "s/\.$//"`
printf '%s %s %s' $country $ipx $hostx
printf '\n'
fi
done
Run Code Online (Sandbox Code Playgroud)
这里的语法如下:
whois
在 IP 地址上运行命令并将输出保存为变量whois_test
。stderr 将被重定向到 /dev/null,当命令失败时不会在屏幕上产生额外的输出。ret
。ret
是否为 0。如果是,则继续执行 for 循环的内容。country
for 循环中变量的赋值略有变化。whois
与最初编写的命令的输出不同,脚本现在通过管道输入whois_test
变量的值。
需要双引号来保留格式,以便grep
正确找到国家/地区的正确值。