Пинг петли Баша успешен - PullRequest
17 голосов
/ 25 мая 2011

Я думаю, что это нужно изменить в условие while, в данный момент оно будет ждать, пока все 10000 пингов не будут выполнены, мне нужно, чтобы оно вернулось, когда пинг будет успешным. Программа "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

ОК. У меня нет прав отвечать на мой вопрос, поэтому вот мой ответ после игры:

Спасибо, да, я не знал о $? до сих пор. Во всяком случае, теперь я пошел и сделал это. Мне нравится, что ваш не вечен, но в моей ситуации мне не нужно было останавливаться, пока он не закончится.

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

Ответы [ 7 ]

28 голосов
/ 25 мая 2011

Вы, вероятно, не должны полагаться на текстовый вывод команды, чтобы решить это, особенно , когда команда ping дает вам очень хорошее возвращаемое значение :

Утилита ping возвращает нулевое состояние завершения, если с указанного хоста был получен хотя бы один ответ;статус два, если передача прошла успешно, но ответы не получены;или другое значение из <sysexits.h>, если произошла ошибка.

Другими словами, используйте что-то вроде:

((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
10 голосов
/ 25 мая 2011

Вам не нужно использовать echo или grep. Вы могли бы сделать это:

ping -oc 100000 8.8.8.8 > /dev/null && say "up" || say "down"
7 голосов
/ 16 октября 2014

Это также можно сделать с таймаутом:

# Ping until timeout or 1 successful packet
ping -w (timeout) -c 1
3 голосов
/ 18 апреля 2014

Я использую этот скрипт 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
3 голосов
/ 25 мая 2011

Если вы используете опцию -o, Mac OS X ping завершит работу после получения одного ответного пакета.

Дополнительная информация: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/ping.8.html

РЕДАКТИРОВАТЬ : 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 выполнит соответствующий оператор.

1 голос
/ 06 марта 2013

Вот мое однострочное решение:

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 my-email@example.com'

Это запускает бесконечный пинг в новом сеансе экрана, пока не будет получен ответ, после чего он отправит электронное письмо на my-email@example.com. Полезно в возрасте электронной почты, отправленной на телефоны.

(Возможно, вы захотите проверить правильность настройки mail, просто запустив сначала echo test | mail -s test my-email@example.com. Конечно, вы можете делать все, что захотите, начиная с done;, звонить в звонок, запускать веб-браузер, использовать свое воображение .)

0 голосов
/ 15 апреля 2018

Мне понравился сценарий 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

У меня также есть Суть этого скрипта , который я буду обновлять с исправлениями и улучшениями по мере необходимости.

...