Bash 使用 while 条件 ping 主机的脚本

Bash script to ping host with while condition

首先,我想说我对bash一无所知,但我正在努力通过实践来学习。

所以,我正在尝试制作一个脚本,它将向远程主机发送一个魔法数据包。当远程主机启动时,我想在显示器上打印点。

我真的没有 wakeonlan 部分的问题,当然我真的不需要脚本来做那件事。但是,为了学习一些有用的东西,我尝试制作一个脚本。

所以我的代码是:

#!/bin/bash 

! timeout 0.5 ping -c1 8.8.8.8 > /dev/null 2>&1
if [ $? -eq 1 ]
then
    echo "Host is up"
else
    wakeonlan FF:FF:FF:FF:FF:FF
    echo "Host is starting ..." 
    while ! ping -c1 -w1 -n 8.8.8.8 > /dev/null 2&>1
    do
            printf "%c" "."
    done
    echo "Host is up!\n\n"

fi
exit 0

现在当主机已经启动时,while 循环退出而不打印。但是,当主机关闭时,它会在显示屏上输出 infinetely 个点,即使主机已启动。 实在不明白为什么while循环在条件满足的时候不停止。

非常感谢您的回答,尤其是如果它符合我的实施。

好的,我想我已经弄清楚这里发生了什么。命令中

while ! ping -c1 -w1 -n 8.8.8.8 > /dev/null 2&>1

&> 的顺序错误。这会导致混乱和意想不到的解释的连锁反应。

具体来说,bash 将 2&>1 解析为参数“2”,然后是重定向 &>1,它将 stdout 和 stderr 发送到名为“1”的文件中.所以它 运行s 这个命令,所有输出为“1”:

ping -c1 -w1 -n 8.8.8.8 2

某些版本的ping会在这里给出error/usage消息,因为它们只接受一个目标IP地址(然后以错误状态退出,使你的循环运行永远)。

其他版本会将 8.8.8.8 解释为在通往最终目的地 2 的途中使用的跃点,这是 IP 地址 0.0.0.2 的旧 shorthand .这在 Internet 上实际上并不存在。这意味着 ping 将失败并以错误状态退出,使你的循环永远 运行。

我怀疑如果您查看文件“1”,您将能够分辨出其中哪些(或可能是其他)正在发生。

这里有一些脚本课程需要学习:

  • 所有那些神秘的符号堆 很重要 ,如果你把它们弄错了一点,你可能会做一些与你想要的完全不同的事情。
  • 丢弃输出(尤其是错误输出)是隐藏错误的好方法。如果脚本有问题,捕获并检查其组件产生的任何错误。
  • set -x 告诉 shell 打印它认为它在执行 运行s 命令时执行的内容,并将其放在脚本中的问题部分之前(然后是 set +x将其关闭)是了解发生了什么的好方法。这就是我发现 bash 将“2”视为参数而不是重定向的一部分的方式。
  • shellcheck.net 很方便!