Bash 循环 ping 成功

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6118948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:33:15  来源:igfitidea点击:

Bash loop ping successful

bashshellunixwhile-loopping

提问by edumike

I'm thinking that this needs to be changed to a while clause, at the moment it'll wait till all 10000 pings are done, I need it to return when the ping is successful. The program "say" is on OSX it makes the computer speak.

我认为这需要更改为 while 子句,目前它会等到所有 10000 个 ping 完成,当 ping 成功时我需要它返回。程序“say”在 OSX 上,它使计算机说话。

#!/bin/bash
echo begin ping
if ping -c 100000 8.8.8.8 | grep timeout;
then echo `say timeout`;
else echo `say the internet is back up`;
fi

OK I don't have rights to answer my own question so here's my answer for it after playing around:

好的,我无权回答我自己的问题,所以这是我玩过之后的答案:

Thanks, yeah I didn't know about $? until now. Anyway now I've gone and made this. I like that yours doesn't go forever but in my situation I didn't need it to stop until it's finished.

谢谢,是的,我不知道 $? 到目前为止。无论如何,现在我已经去做了。我喜欢你的不会永远消失,但在我的情况下,我不需要它在完成之前停止。

#!/bin/bash
intertube=0
echo "begin ping"
while [ $intertube -ne 1 ]; do
        ping -c 3 google.com
        if [ $? -eq  0 ]; then
                echo "ping success";
                say success
                intertube=1;
        else
                echo "fail ping"
        fi
done
echo "fin script"

回答by paxdiablo

You probably shouldn't rely on textual output of a command to decide this, especiallywhen the pingcommand gives you a perfectly good return value:

您可能不应该依赖命令的文本输出来决定这一点,尤其是当该ping命令为您提供非常好的返回值时

The ping utility returns an exit status of zero if at least one response was heard from the specified host; a status of two if the transmission was successful but no responses were received; or another value from <sysexits.h>if an error occurred.

如果至少从指定主机听到一个响应,ping 实用程序将返回退出状态为零;如果传输成功但未收到响应,则状态为 2;或<sysexits.h>发生错误时的其他值。

In other words, use something like:

换句话说,使用类似的东西:

((count = 100))                            # Maximum number to try.
while [[ $count -ne 0 ]] ; do
    ping -c 1 8.8.8.8                      # Try once.
    rc=$?
    if [[ $rc -eq 0 ]] ; then
        ((count = 1))                      # If okay, flag to exit loop.
    fi
    ((count = count - 1))                  # So we don't go forever.
done

if [[ $rc -eq 0 ]] ; then                  # Make final determination.
    echo `say The internet is back up.`
else
    echo `say Timeout.`
fi

回答by Rob Davis

You don't need to use echo or grep. You could do this:

您不需要使用 echo 或 grep。你可以这样做:

ping -oc 100000 8.8.8.8 > /dev/null && say "up" || say "down"

回答by MikeTwo

This can also be done with a timeout:

这也可以通过超时来完成:

# Ping until timeout or 1 successful packet
ping -w (timeout) -c 1

回答by Michaelangel007

I use this Bash script to test the internet status every minute on OSX

我使用这个 Bash 脚本在 OSX 上每分钟测试一次互联网状态

#address=192.168.1.99  # forced bad address for testing/debugging
address=23.208.224.170 # www.cisco.com
internet=1             # default to internet is up

while true;
do
    # %a  Day of Week, textual
    # %b  Month, textual, abbreviated
    # %d  Day, numeric
    # %r  Timestamp AM/PM
    echo -n $(date +"%a, %b %d, %r") "-- " 
    ping -c 1 ${address} > /tmp/ping.$
    if [[ $? -ne 0 ]]; then
        if [[ ${internet} -eq 1 ]]; then   # edge trigger -- was up now down
            echo -n $(say "Internet down") # OSX Text-to-Speech
            echo -n "Internet DOWN"
        else
            echo -n "... still down"
        fi
        internet=0
    else
        if [[ ${internet} -eq 0 ]]; then     # edge trigger -- was down now up
            echo -n $(say "Internet back up") # OSX Text-To-Speech
        fi
        internet=1
    fi   
    cat /tmp/ping.$ | head -2 | tail -1
    sleep 60 ; # sleep 60 seconds =1 min
done

回答by Lawrence Velázquez

If you use the -ooption, Mac OS X's pingwill exit after receiving one reply packet.

如果使用该-o选项,Mac OS Xping将在收到一个回复​​包后退出。

Further reading: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/ping.8.html

进一步阅读:http: //developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/ping.8.html

EDIT: paxdiablo makes a very good pointabout using ping's exit status to your advantage. I would do something like:

编辑paxdiablo 很好地说明了使用ping的退出状态对您有利。我会做这样的事情:

#!/usr/bin/env bash
echo 'Begin ping'
if ping -oc 100000 8.8.8.8 > /dev/null; then
    echo $(say 'timeout')
else
    echo $(say 'the Internet is back up')
fi

pingwill send up to 100,000 packets and then exit with a failure status—unless it receives one reply packet, in which case it exits with a success status. The ifwill then execute the appropriate statement.

ping将发送多达 100,000 个数据包,然后以失败状态退出——除非它收到一个回复​​数据包,在这种情况下它以成功状态退出。然后if将执行适当的语句。

回答by pwaller

Here's my one-liner solution:

这是我的单线解决方案:

screen -S internet-check -d -m -- bash -c 'while ! ping -c 1 google.com; do echo -; done; echo Google responding to ping | mail -s internet-back [email protected]'

This runs an infinite ping in a new screen session until there is a response, at which point it sends an e-mail to [email protected]. Useful in the age of e-mail sent to phones.

这会在新的 screen 会话中运行无限 ping 直到有响应,此时它会向 发送电子邮件[email protected]。在电子邮件发送到手机的时代很有用。

(You might want to check that mailis configured correctly by just running echo test | mail -s test [email protected]first. Of course you can do whatever you want from done;onwards, sound a bell, start a web browser, use your imagination.)

(您可能想mail通过echo test | mail -s test [email protected]首先运行来检查配置是否正确。当然,您可以从done;以后做任何您想做的事情,敲响铃声,启动 Web 浏览器,发挥您的想象力。)

回答by John Karahalis

I liked paxdiablo's script, but wanted a version that ran indefinitely. This version runs ping until a connection is established and then prints a message saying so.

我喜欢 paxdiablo 的脚本,但想要一个可以无限运行的版本。此版本运行 ping 直到建立连接,然后打印一条消息。

echo "Testing..."

PING_CMD="ping -t 3 -c 1 google.com > /dev/null 2>&1"

eval $PING_CMD

if [[ $? -eq 0 ]]; then
    echo "Already connected."
else
    echo -n "Waiting for connection..."

    while true; do
        eval $PING_CMD

        if [[ $? -eq 0 ]]; then
            echo
            echo Connected.
            break
        else
            sleep 0.5
            echo -n .
        fi
    done
fi

I also have a Gist of this scriptwhich I'll update with fixes and improvements as needed.

我还有这个脚本要点,我将根据需要更新修复和改进。