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"
[p@localhost ~]$ VBoxManage startvm VGTU-2021-LDVM1 --type headless && \
> ping 192.168.10.14 | sed "/ ms$/ q"
Waiting for VM "VGTU-2021-LDVM1" to power on...
VM "VGTU-2021-LDVM1" has been successfully started.
PING 192.168.10.14 (192.168.10.14) 56(84) bytes of data.
From 192.168.10.8 icmp_seq=1 Destination Host Unreachable
From 192.168.10.8 icmp_seq=2 Destination Host Unreachable
...
From 192.168.10.8 icmp_seq=35 Destination Host Unreachable
From 192.168.10.8 icmp_seq=36 Destination Host Unreachable
64 bytes from 192.168.10.14: icmp_seq=37 ttl=64 time=2003 ms
Martynas 回答的进一步简化:
注意 ping 本身被用作循环测试;一旦成功,循环结束。循环体为空,空命令“
:
”用于防止语法错误。更新:我想到了一种让 Control-C 干净地退出 ping 循环的方法。这将在后台运行循环,捕获中断(Control-C)信号,并在发生时终止后台循环:
这有点迂回,但如果你希望循环可以取消,它应该可以解决问题。
我知道这个问题很老......并且特别询问关于
ping
,但我想分享我的解决方案。我在重新启动主机时使用它来了解何时可以再次通过 SSH 连接到它们。(因为
ping
会在开始前响应几秒钟sshd
。)您可以执行一个循环,发送一个 ping 并根据状态中断循环,例如(bash):
将它放在脚本中的某个位置会阻塞,直到
www.google.com
可以 ping 通为止。ping 目标主机一次。检查 ping 是否成功(ping 的返回值为零)。如果主机不存在,请再次 ping。
以下代码可以保存为文件并使用主机名作为参数调用,或者剥离第一行和最后一行并用作现有脚本中的函数(waitForHost 主机名)。
如果 ping 没有导致响应,则代码不会评估失败的原因,因此如果主机不存在,则永远循环。我的 BSD 手册页列出了每个返回值的含义,而 linux 没有,所以我想这可能不是可移植的,这就是我忽略它的原因。
您可以删除 sleep 1,它只是为了防止任何洪水问题,以防主机可以访问但 ping 不会以代码 0 退出。
请在stackoverflow上查看好的选项。这是 bash 中的示例,您必须循环以下代码,直到它返回成功的 ping 结果。
上述任何循环也可以与 fping 一起使用,而不是 ping,IMO 比 ping 本身更适合在脚本中使用。有关详细信息,请参阅fping(1)。
在对机器进行操作之前测试机器是否已启动也很有用。一个简单的例子:
对于 macOS 用户,
ping
有-o
专门用于此的选项:所以命令很简单:
当主机被成功 ping 一次时返回 0。
一般来说,我想等待我的数据库或其他服务器启动,但我不想等待太久。以下代码等待 10 秒,然后如果服务器未在时间限制内出现,则设置退出代码。
如果服务器在时间限制之前出现,则循环将被短路,以便下一段代码可以运行。
伙计们,是的,这是旧的。这里有很多很好的答案。
但我刚刚发现了我所谓的美女!如果有人喜欢原生
ping
计数器:ping $HOST | sed "/ ms$/ q"
这不是很迷人吗?:)