호스트가 알려질 때까지 리눅스에서 핑하는 방법?


46

특정 주소를 핑 (ping)하는 방법과 발견되면 핑 (ping)을 중지하십시오.

bash 스크립트에서 사용하고 싶습니다. 따라서 호스트가 시작될 때 스크립트는 핑을 유지하고 호스트가 사용 가능한 순간부터 스크립트가 계속됩니다 ...

답변:


84

Martynas의 답변을 더 단순화 :

until ping -c1 www.google.com >/dev/null 2>&1; do :; done

핑 자체는 루프 테스트로 사용됩니다. 성공하자마자 루프가 종료됩니다. :구문 오류를 방지하기 위해 널 명령 " "을 사용하여 루프 본문이 비어 있습니다.

업데이트 : Control-C가 ping 루프를 깨끗하게 종료하는 방법을 생각했습니다. 백그라운드에서 루프를 실행하고 인터럽트 (Control-C) 신호를 포착하고 백그라운드 루프가 발생하면 종료합니다.

ping_cancelled=false    # Keep track of whether the loop was cancelled, or succeeded
until ping -c1 "$1" >/dev/null 2>&1; do :; done &    # The "&" backgrounds it
trap "kill $!; ping_cancelled=true" SIGINT
wait $!          # Wait for the loop to exit, one way or another
trap - SIGINT    # Remove the trap, now we're done with it
echo "Done pinging, cancelled=$ping_cancelled"

약간 회로가 좋지만 루프를 취소하려면 트릭을 수행해야합니다.


6
'수면'을 추가하려면 (예 : 5 초마다) : while! 핑 -c1 www.google.com &> / dev / null; 잠을 5; 완료
lepe

4
기본적 ping으로 핑을 포기하기 전에 10 초 정도 기다립니다. 이를 1 초로 줄이려면을 사용할 수 있습니다 -w1.
잭 오코너

2
@ JackO'Connor BSD 핑을 사용하는이 곳은 수도입니다.-W1
Luke Exton

이 답변의 유일한 문제는 SIGINT를 잘 처리하지 못한다는 것입니다. 어떤 이유로 든 연결되지 않으면 명령 행에서이를 중지 할 수 없습니다.
Luke Exton

@LukeExton bash와 ping이 SIGINT를 처리하는 방식과 이들이 상호 작용하는 방식 때문입니다 ( 이 질문 참조 ). 나는 좋은 해결책이 없지만 kluge가 있습니다. Control-Z를 사용하여 스크립트를 중지 한 다음 kill %1죽이십시오.
Gordon Davisson

25

루프를 수행하고 하나의 핑을 보내고 상태에 따라 루프를 끊을 수 있습니다 (예 : bash).

while true; do ping -c1 www.google.com > /dev/null && break; done

www.google.com핑이 가능할 때까지 스크립트의 어딘가에 넣으면 차단됩니다 .


2
while true과는 breakIMO, 청소기 솔루션입니다.
Dan Carley

1
@ DanCarley 허용 된 답변에서 null 명령 버전에서 휴면 / 대기를 대체하여 CPU에 휴식을 줄 수 있기 때문에 동의하지 않을 것입니다.이 경우 더 깨끗한 솔루션이라고합니다. 이 답변의 다른 문제는 독자 / 사용자가 &&의 작동 방식을 이해하고 첫 번째 명령이 실패하면 호출되지 않는 방식을 이해해야한다는 것입니다. 이것은 당신과 같은 의견 일뿐입니다.
Hamid

1
이 솔루션과 허용되는 솔루션의 주요 차이점은이 메시지가 발견 될 때까지 "알 수없는 호스트 ..."라는 오류 메시지를 표시한다는 것입니다. 수면 을 추가하려면 (예 : 5 초마다) :while true; do sleep 5; ping ...
lepe

20

나는 질문이 오래되었다는 것을 알고 있습니다. 특히에 대해 묻지 ping만 솔루션을 공유하고 싶었습니다.

호스트를 재부팅 할 때 SSH를 다시 ​​연결할 수있는 시점을 알 때 사용합니다. ( 시작 ping하기 전에 몇 초 동안 응답합니다 sshd.)

until nc -vzw 2 $host 22; do sleep 2; done

2
바로 내가 찾은 것입니다. 감사합니다! 이 스레드의 다른 솔루션에는 해당되지 않는 CTRL + C를 사용하여 호출을 중단 할 수도 있습니다.
Alex

1
netcat의 BSD 버전에서 작동합니다. Linux 배포판의 nmap.org 버전은 다르게 구현되므로 -z 옵션이 존재하지 않으며 -w 옵션은 연결을 기다리지 만 성공하면 닫히지 않습니다. 그러나 OSX에서 훌륭하게 작동합니다.
Paul

이것이 첫 번째 정답에서 멈추지 않는 이유입니다. 이것이 실제 문제에 대한 해답 입니다.
Leo

11

대상 호스트를 한 번 핑하십시오. Ping에 성공했는지 확인하십시오 (Ping의 반환 값이 0 임). 호스트가 활성 상태가 아닌 경우 다시 핑하십시오.

다음 코드는 파일로 저장하고 호스트 이름을 인수로 사용하여 호출하거나 첫 번째 및 마지막 행을 제거하여 기존 스크립트 (waitForHost 호스트 이름) 내에서 함수로 사용할 수 있습니다.

핑이 응답하지 않으면 코드는 실패 원인을 평가하지 않으므로 호스트가 존재하지 않으면 영원히 반복됩니다. 내 BSD 맨 페이지에는 각 반환 값의 의미가 나열되어 있지만 Linux는 그렇지 않으므로 이식성이 없을 수도 있으므로 생략했습니다.

#!/bin/bash

PING=`which ping`

function waitForHost
{
    if [ -n "$1" ]; 
    then
        waitForHost1 $1;
    else
        echo "waitForHost: Hostname argument expected"
    fi
}

function waitForHost1
{
    reachable=0;
    while [ $reachable -eq 0 ];
    do
    $PING -q -c 1 $1
    if [ "$?" -eq 0 ];
    then
        reachable=1
    fi
    done
    sleep 5
}
waitForHost $1

9
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ]; 
   do ping -q -c 1 HOST &> /dev/null; UNREACHEABLE=$?; sleep 1;
done

수면 1을 제거 할 수 있습니다. 호스트에 도달 할 수 있지만 핑이 코드 0으로 종료되지 않는 경우 홍수 문제를 방지하기 위해 여기에 있습니다.


4

stackoverflow 에서 좋은 옵션을 참조하십시오 . 다음은 bash의 샘플입니다. 성공적인 ping 결과를 반환 할 때까지 다음 코드를 반복해야합니다.


ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
    echo "192.168.1.1 is up";
else 
    echo "ip is down";
fi


3

위의 루프 중 하나를 ping 대신 fping과 함께 사용할 수 있습니다. IMO는 ping 자체보다 스크립트에 사용하기에 더 적합합니다. 자세한 내용은 fping (1) 을 참조하십시오.

while ! fping -q $HOSTNAMES ; do :; done

또한 기계가 작동하기 전에 기계가 작동 중인지 테스트하는 데 유용합니다. 간단한 예 :

HOST1에서 h 동안 HOST2 HOST3; 하다
  fping -q $ h이면; 그때
     echo -n "$ h :"
     ssh $ h "uname -a"
  fi
끝난

1

주어진 횟수만큼 시도합니다.

t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r

에코하는 대신 $r테스트하고 값에 따라 작동 할 수 있습니다.

if ((r)); then echo 'Failed to contact host'; else echo 'Continuing with script'; fi

1

BSD 핑에서 SIGINT를 잘 처리합니다.

HOST=google.com NO=1; while [ $NO -ne 0 ]; do ping -W1 -c1 $HOST &>/dev/null; NO=$?;echo "$(date) ($HOST) $NO" ; done; echo "$(date) ($HOST) reachable"

기능으로서

ping_until(){
  local NO=1
  while [ $NO -ne 0 ]; do
    ping -W1 -c1 $1 &>/dev/null; NO=$?
    # Optionally block ICMP flooding
    # sleep 1
    echo "$(date) ($1) ($NO)"
  done
}

0

다음 기능을 사용하고 있습니다. 잠시 후 시도를 중단하도록 지시 할 수 있기 때문에 좋아합니다.

#!/usr/bin/env bash

function networkup {
  # Initialize number of attempts
  reachable=$1
  while [ $reachable -ne 0 ]; do
    # Ping supplied host
    ping -q -c 1 -W 1 "$2" > /dev/null 2>&1
    # Check return code
    if [ $? -eq 0 ]; then
      # Success, we can exit with the right return code
      echo 0
      return
    fi
    # Network down, decrement counter and try again
    let reachable-=1
    # Sleep for one second
    sleep 1
  done
  # Network down, number of attempts exhausted, quiting
  echo 1
}

다음과 같이 사용하여 무언가를 시작할 수 있습니다.

# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
  firefox &
fi

0

일반적으로 데이터베이스 또는 다른 서버가 나타날 때까지 기다리려고하지만 너무 오래 기다리지 않습니다 . 다음 코드는 10 초 동안 기다린 다음 서버가 시간 제한 내에 나타나지 않으면 종료 코드를 설정합니다.

서버가 시간 제한 이전에 나타나면 루프가 단락되어 다음 코드 비트가 실행될 수 있습니다.

for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${HOST} &>/dev/null && break ; done

0

Gordon Davisson의 답변에 대한 추가 개선 사항 :

until $(ping -c1 www.google.com &>/dev/null); do :; done

주변 '$ ()'을 사용하면 서브 쉘이 시작되므로 호스트를 사용할 수없는 경우 Control-C를 사용하여 루프를 종료 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.