在 shell 脚本中处理 whois 连接被拒绝的消息

Nec*_*cco 2 shell-script

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错误并做出正确反应?

clk*_*clk 5

您可以通过使用 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)

这里的语法如下:

  1. whois在 IP 地址上运行命令并将输出保存为变量whois_test。stderr 将被重定向到 /dev/null,当命令失败时不会在屏幕上产生额外的输出。
  2. 将退出状态的值分配给变量ret
  3. If 语句检查变量的值ret是否为 0。如果是,则继续执行 for 循环的内容。

countryfor 循环中变量的赋值略有变化。whois与最初编写的命令的输出不同,脚本现在通过管道输入whois_test变量的值。

需要双引号来保留格式,以便grep正确找到国家/地区的正确值。