Bash 循环 ping 成功

发布于 2024-11-09 10:01:17 字数 707 浏览 4 评论 0原文

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

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

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

谢谢,是的,我不知道 $?到目前为止。不管怎样,现在我已经做了这个。我喜欢你的不会永远消失,但在我的情况下,我不需要它停止,直到它完成。

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

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

抹茶夏天i‖ 2024-11-16 10:01:18

这是我的单行解决方案:

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]'

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

(您可能想通过运行 echo test | mail -s test [email protected]。当然,你可以做任何你想做的事情,从done;开始,响铃,开始网络浏览器,发挥你的想象力。)

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.

(You might want to check that mail is 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.)

南冥有猫 2024-11-16 10:01:18

我喜欢 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 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.

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 script which I'll update with fixes and improvements as needed.

红墙和绿瓦 2024-11-16 10:01:17

您可能不应该依赖命令的文本输出来决定这一点,尤其是ping命令给你一个完美的返回值

如果从指定主机至少听到一个响应,则 ping 实用程序返回退出状态为零;如果传输成功但未收到响应,则状态为 2;或者如果发生错误,则来自 的另一个值。

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

((count = 60))                           # 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 loop exit.
    else
        sleep 1                          # Minimise network storm.
    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

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

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.

In other words, use something like:

((count = 60))                           # 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 loop exit.
    else
        sleep 1                          # Minimise network storm.
    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
ゞ记忆︶ㄣ 2024-11-16 10:01:17

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

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

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

ping -oc 100000 8.8.8.8 > /dev/null && say "up" || say "down"
随遇而安 2024-11-16 10:01:17

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

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

This can also be done with a timeout:

# Ping until timeout or 1 successful packet
ping -w (timeout) -c 1
烟燃烟灭 2024-11-16 10:01:17

如果您使用 -o 选项,BSD ping(也在 macOS 上)将在收到一个回复​​数据包后退出。

进一步阅读: https://www.freebsd.org/cgi/man.cgi ?query=ping

编辑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

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

编辑2:克里斯指出我的逻辑是相反的,这真是令人尴尬。此外,echo 命令(从问题继承)没有任何作用,并且不需要专门要求 bash。我对12年前的自己很失望。今天我会写:

#!/bin/sh
if ping -oc 100000 8.8.8.8 >/dev/null; then
    say 'the Internet is back up'
else
    say timeout
fi

If you use the -o option, BSD ping (which is also on macOS) will exit after receiving one reply packet.

Further reading: https://www.freebsd.org/cgi/man.cgi?query=ping

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

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

ping will 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 if will then execute the appropriate statement.

EDIT 2: Chris points out that my logic is reversed, which is just embarrassing. Additionally, the echo commands (inherited from the question) serve no purpose, and there's no need to require bash specifically. I'm disappointed in 12-years-ago me. Today I would write:

#!/bin/sh
if ping -oc 100000 8.8.8.8 >/dev/null; then
    say 'the Internet is back up'
else
    say timeout
fi
青瓷清茶倾城歌 2024-11-16 10:01:17

我使用这个 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

I use this Bash script to test the internet status every minute on 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文