Bash等待ping成功


10

我正在写一个脚本来重新启动各种服务器。重新启动后,我要“等待”,直到所有服务器重新联机。(为简单起见,我在网上为我定义了可ping通的内容)

所以对于每个服务器

ServerXY_W=1
echo -n "waiting for ServerXY ..."
while (($ServerXY_W == 1))
do
   if ping -c 1 -w 0.2 192.168.123.123 &> /dev/null
   then
      echo "ServerXY is back online!"
      ServerXY_W=0
   else
      echo -n "."
   fi
done

我所期望的(和类似的)将是输出,例如

waiting for ServerXY .................
ServerXY is back online!

点...将一一出现。

但是实际上发生的是首先只有

waiting for ServerXY ...

有一会儿,当服务器返回时,我得到最后一个点和最后一行

waiting for ServerXY ....
ServerXY is back online!

为什么while循环只执行两次,如一次ping失败和一次ping成功?我必须更改什么才能在while循环中添加更多的点?

我也使用不存在的IP进行了测试。但是它卡住了

waiting for NonExistentServer...

从来没有终止过 但是同样的问题,为什么不........添加?


对我来说很好...:/
Ravexina

Answers:


9

问题

问题是你已经设置好了-w 0.2。当值小于1时,截止时间(-w)和超时(-W)值将被忽略。这个问题之前已经提到过。当您使用时-w 1,您的脚本(我对此脚本做了一些修改,以删除无用的位)可以正常工作:

$ ./ping_server.sh                                                 
waiting for ServerXY ....................
Server is back online

$ cat ./ping_server.sh
#!/bin/bash
printf "%s" "waiting for ServerXY ..."
while ! ping -c 1 -n -w 1 147.153.237.192 &> /dev/null
do
    printf "%c" "."
done
printf "\n%s\n"  "Server is back online"

明显的解决方法是使用-w 1。如果您打算使用小于1秒的值,则该timeout命令应该更好:

$ timeout 0.2 ping -c 1 147.153.237.192                            
PING 147.153.237.192 (147.153.237.192) 56(84) bytes of data.
64 bytes from 147.153.237.192: icmp_seq=1 ttl=124 time=2.61 ms

--- 147.153.237.192 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.612/2.612/2.612/0.000 ms

同样,!在循环中将它与operator一起使用:

#!/bin/bash
printf "%s" "waiting for ServerXY ..."
while ! timeout 0.2 ping -c 1 -n 147.153.237.192 &> /dev/null
do
    printf "%c" "."
done
printf "\n%s\n"  "Server is back online"

当然,仅当服务器启动时才显示相反的消息,而当服务器关闭时才报告,例如:

$ while ping -q -c 1 172.16.127.2 >/dev/null ; do sleep 1; done ; echo "Server stopped responding"
Server stopped responding

但是请注意,这并不完美:

  • 我们每秒仅轮询1个数据包。低带宽,低连接性,服务器与客户端对服务器执行ping操作之间的不良硬件将触发循环退出并发出误报通知

  • 我们依赖ping,即使用ICMP回显。防火墙甚至单个服务器都会阻止对ping / ICMP回显的响应。你可以使用ncncat(这是一个改进版本nc)。类似于上面循环中的内容,它可以代替ping

    nc -w5 -z 172.16.127.2 80

    这样做是为了在端口80上连接172.16.127.2上的服务器。-z为避免I / O,只需连接和断开连接即可。-w报告连接失败之前要等待5秒钟。当然,这对您有控制权的服务器并且您知道端口80是开放的非常有用。可以很好地使用UPD,但是如果有防火墙,则可能首选TCP。

    这里的一个隐藏好处是,如果您有某些服务在特定端口上运行(例如,端口80上的HTTP或554上的RTSP),则无法连接到端口可能表示您的服务需要重新启动。

  • 当然,nc而且ping可能有点垃圾邮件。更好的方法是让服务器与另一台中央服务器签到,并可能每隔一个小时发送一次定期报告。这样,如果服务器错过了“打卡时间”,则可能会产生错误。更好的方法是使用Nagios之类的服务。但是目前,我们正在进入具有多台服务器的企业级计算领域。如果家里有类似Raspberry Pi的产品,则可能不需要任何复杂的东西。


嗨,非常感谢您清除-w内容!除了在循环条件下进行操作之外,还有其他方法吗?这是等待一台服务器的理想选择,但是如上所述,我正在等待多台服务器,稍后我会做一些类似的事情while (( $ServerA_W==1 || $ServerB_W==1 || .....)),当每台服务器返回时,它都会保留。
derHugo

例如,在一台服务器返回等待其他服务器之后,我不想对已经返回的服务器进行ping操作;)
derHugo

我建议将其编写为函数,并在后台以ip地址作为参数启动每个函数的实例。但是我建议不要打印点,只在服务器启动时让每个函数打印消息。让我知道是否要我写一个这样的功能的示例
Sergiy Kolodyazhnyy

1
@Joanne是的,有可能。我可以在今天晚些时候或明天更新我的答案。就个人而言,我不会连续ping服务器,因为它有点垃圾,不过
Sergiy Kolodyazhnyy

1
@Joanne在答案中查看我的更新。让我知道这是否有帮助或是否有其他问题
Sergiy Kolodyazhnyy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.