web-dev-qa-db-fra.com

Bash loop ping réussi

Je pense que cela doit être changé pour une clause while, au moment où il faudra attendre que toutes les 10000 pings soient terminés, j'ai besoin que ça revienne quand le ping est réussi. Le programme "say" est sur OSX, il fait parler l'ordinateur.

#!/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, je n'ai pas le droit de répondre à ma propre question, alors voici ma réponse après avoir joué:

Merci, ouais je ne savais pas à propos de $? jusqu'à maintenant. En tout cas maintenant, je suis parti et j'ai fait ça. J'aime que le tien ne disparaisse pas éternellement, mais dans ma situation, je n'avais pas besoin de m'arrêter avant d'avoir fini.

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

Vous ne devriez probablement pas vous fier à la sortie textuelle d’une commande pour décider de cela, surtout lorsque la commande pingvous donne une valeur de retour parfaitement correcte :

L'utilitaire ping renvoie un état de sortie égal à zéro si au moins une réponse a été entendue de l'hôte spécifié. statut deux si la transmission a réussi mais qu'aucune réponse n'a été reçue; ou une autre valeur de <sysexits.h> en cas d'erreur.

En d'autres termes, utilisez quelque chose comme:

((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
26
paxdiablo

Vous n'avez pas besoin d'utiliser echo ou grep. Vous pourriez faire ceci:

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

Cela peut aussi être fait avec un timeout:

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

Si vous utilisez l’option -o, la ping de Mac OS X se ferme après la réception d’un paquet de réponse.

Pour en savoir plus: http://developer.Apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/ping.8.html

EDIT: paxdiablo fait un très bon point à propos de l’utilisation du statut de sortie de ping à votre avantage. Je ferais quelque chose comme:

#!/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 enverra jusqu'à 100 000 paquets, puis se terminera avec un statut d'échec, à moins qu'il ne reçoive un paquet de réponse, auquel cas il se terminera avec un statut de réussite. La if exécutera ensuite l'instruction appropriée.

3

J'utilise ce script Bash pour tester l'état d'Internet chaque minute sur 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
Michaelangel007

Voici ma solution one-liner:

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

Ceci exécute un ping infini dans une nouvelle session d'écran jusqu'à ce qu'il y ait une réponse, à quel point il envoie un courrier électronique à [email protected]. Utile à l'ère du courrier électronique envoyé aux téléphones.

(Vous voudrez peut-être vérifier que mail est configuré correctement en exécutant simplement echo test | mail -s test [email protected]. Bien sûr, vous pouvez faire ce que vous voulez à partir de done;, sonner une cloche, démarrer un navigateur Web, utiliser votre imagination.)

1
pwaller

J'ai aimé le script de paxdiablo, mais je voulais une version indéfiniment. Cette version exécute une commande ping jusqu'à ce qu'une connexion soit établie, puis affiche un message l'informant.

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

J'ai aussi un Résumé de ce script que je mettrai à jour avec les corrections et améliorations nécessaires.

0
John Karahalis