핑 성공을 기다리는 배쉬


10

다양한 서버를 재부팅하는 스크립트를 작성 중입니다. 재부팅 후 모든 서버가 다시 온라인 상태가 될 때까지 "대기"하고 싶습니다. (내가 온라인으로 정의한 것을 간단하게 유지하기 위해 = 핑 가능)

그래서 각 서버마다

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!

왜 ping이 실패하고 ping이 성공하면 while 루프가 두 번만 수행됩니까? while 루프에 더 많은 점을 추가하려면 무엇을 변경해야합니까?

존재하지 않는 IP로도 테스트를 수행했습니다. 그러나 그것은 붙어

waiting for NonExistentServer...

물론 끝나지 않았습니다. 그러나 같은 질문이 왜 ........추가 되지 않습니까?


나를 위해 잘 작동 ... : /
Ravexina

답변:


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

다시 !루프에서 연산자 와 함께 사용하십시오 .

#!/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) 사이의 낮은 대역폭, 연결 불량, 하드웨어 불량으로 인해 루프가 종료되고 잘못된 긍정 알림이 발생합니다.

  • 우리는 ICMP 에코를 사용하는 핑에 의존하고 있습니다. 방화벽 또는 개별 서버조차도 ping / ICMP 에코에 대한 응답을 차단합니다. 당신은 사용할 수 ncncat(의 개선 된 버전이다 nc). 위의 루프와 같은 것이 대신 잘 작동합니다 ping.

    nc -w5 -z 172.16.127.2 80

    이 작업은 포트 80의 172.16.127.2에서 서버에 연결하는 것입니다. -zI / O를 피하기 위해 연결하고 연결을 끊기 만하면됩니다. -w연결 실패를보고하기 전에 5 초 동안 대기하는 것입니다. 물론 이것은 서버를 제어 할 수 있고 포트 80이 열려 있다는 것을 알 때 매우 좋습니다. UPD는 잘 사용할 수 있지만 방화벽이 있으면 TCP가 선호됩니다.

    여기서 숨겨진 이점은 특정 포트에서 일부 서비스 (예 : 포트 80의 HTTP 또는 554의 RTSP)를 실행하는 경우 포트에 연결하지 못하면 서비스를 다시 시작해야한다는 표시로 작용할 수 있다는 것입니다.

  • 물론, ncping비트 스팸이 될 수 있습니다. 더 나은 방법은 다른 중앙 서버와 서버를 체크인하고 매 시간마다 정기적 인 보고서를 보내는 것입니다. 이렇게하면 서버에 "펀치 시간"이 없으면 오류가 발생할 수 있습니다. 더 좋은 방법은 Nagios와 같은 서비스를 사용하는 것입니다. 그러나이 시점에서 우리는 여러 서버가있는 엔터프라이즈 급 컴퓨팅 영역으로 들어가고 있습니다. 집에 Raspberry Pi와 같은 것이 있다면 복잡한 것이 필요하지 않을 것입니다.


안녕-w 물건을 지워 주셔서 대단히 감사합니다! 루프 조건에서 수행하는 것과 다른 방법이 있습니까? 하나의 서버를 기다리는 데는 완벽하지만 언급 한 것처럼 나중에 여러 서버를 기다리고 while (( $ServerA_W==1 || $ServerB_W==1 || .....))있습니다. 모든 서버가 돌아올 때 보유하고 있는 것과 같은 일 을합니다.
derHugo 2016 년

예를 들어 한 서버가 다른 서버를 다시 기다리는 경우 이미 돌아온 서버를 핑하고 싶지 않습니다.)
derHugo

함수로 작성하고 백그라운드에서 인수로 ip 주소를 사용하여 각 함수의 인스턴스를 시작하는 것이 좋습니다. 그러나 점을 인쇄하지 않는 것이 좋습니다. 서버가 나타나면 각 기능이 메시지를 인쇄하도록하십시오. 그러한 기능의 예를 작성하고 싶은지 알려주세요
Sergiy Kolodyazhnyy

1
@Joanne 네, 가능합니다. 오늘이나 내일 늦게 답변을 업데이트 할 수 있습니다. 그것은 비록 조금 스팸이기 때문에 개인적으로, 나는 지속적으로 서버를 Ping 할 것
세르지 Kolodyazhnyy

1
@Joanne 답변에서 내 업데이트를 확인하십시오. 도움이되는지 또는 다른 질문이 있으면 알려주십시오
Sergiy Kolodyazhnyy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.