it-swarm.cn

在主机已知之前,如何在Linux中进行ping操作?

如何查验某个地址,找到后就停止查验。

我想在bash脚本中使用它,所以当主机启动时,脚本会继续ping并且从主机可用的那一刻起,脚本便会继续...

50
Sander Versluys

Martynas的答案进一步简化:

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

注意ping本身用作循环测试;一旦成功,循环就会结束。循环体为空,使用空命令“ :”用于防止语法错误。

更新:我想到了一种使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"

这有点circuit回,但是如果您希望循环可取消,则可以解决问题。

87
Gordon Davisson

您可以进行循环,发送一次ping操作,然后根据状态中断循环,例如(bash):

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

将其放在脚本中的某个位置将阻止,直到www.google.com是可ping通的。

25
Martynas Saint

我知道这个问题很旧...并特别询问ping,但我想分享我的解决方案。

在重新引导主机时,我会用它来知道何时可以再次通过SSH重新登录它们。 (因为ping将在启动sshd之前响应几秒钟。)

until nc -vzw 2 $Host 22; do sleep 2; done
22
Aaron Copley

对目标主机执行一次ping操作。检查ping是否成功(ping的返回值为零)。如果主机不存在,请再次ping通。

可以将以下代码另存为文件,并以主机名作为参数进行调用,或者除去第一行和最后一行,并在现有脚本(waitForHost主机名)中用作函数。

如果ping不导致响应,则代码不会评估失败的原因,因此如果主机不存在,则会永远循环。我的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
11
Jan Jungnickel
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ]; 
   do ping -q -c 1 Host &> /dev/null; UNREACHEABLE=$?; sleep 1;
done

您可以删除睡眠1,仅在这里可以防止任何洪泛问题,以防主机可访问但ping不会以代码0退出。

9
radius

请在 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
4
Francois Wolmarans

以上任何循环也可以与fping一起使用,而不是与ping相比更适合ping,而IMO更适合在脚本中使用。有关详细信息,请参见 fping(1)

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

在对机器进行某些操作之前测试机器是否已启动也很有用。一个简单的例子:

 for h in Host1 Host2 Host3;如果fping -q $ h,请执行
;然后
 echo -n“ $ h:” 
 ssh $ h“ uname -a” 
 fi 
完成
3
cas

为了更好地处理BSD ping上的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
}
1
Luke Exton

这将尝试给定的次数。

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

对于macOS用户,ping可以选择-o专为此:

-o      Exit successfully after receiving one reply packet.

所以命令很简单:

ping -o www.google.com

当主机成功ping通一次后,它将返回0。

1
Melebius

通常,我想等待数据库或其他服务器启动,但是我不想等too很长。下面的代码等待10秒钟,如果服务器未在期限内出现,则设置退出代码。

如果服务器出现在时间限制之前,则该循环将被短路,因此下一段代码可以运行。

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

我一直在使用以下功能。我喜欢它,因为我可以告诉它在一段时间后停止尝试:

#!/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
oneself

戈登·戴维森的答案的进一步增强:

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

使用周围的“ $()”启动一个子shell,因此,如果主机不可用,则可以使用Control-C终止循环。

0
Shawn