2009-08-04 15 views
7

Guten Tag! Gibt es eine Möglichkeit, einen Timer (Timestamp? Oder was auch immer?) In ein Skript mit Bash? Wie zum Beispiel; Alle 60 Sekunden überprüft eine bestimmte Funktion, ob das Internet ausgefallen ist. Wenn dies der Fall ist, wird stattdessen eine Verbindung zum WLAN-Gerät hergestellt und umgekehrt. Kurz gesagt, das Programm überprüft die Internetverbindung von Zeit zu Zeit.Wie fügt man einen Timer in Bash Scripting ein?

Alle Vorschläge/Antworten werden sehr geschätzt. =)

Antwort

18

Blunt Version

while sleep 60; do 
    if ! check_internet; then 
    if is_wifi; then 
     set_wired 
    else 
     set_wifi 
    fi 
    fi 
done 

Mit dem Schlaf selbst als Schleifenbedingung Sie können durch aus der Schleife brechen den Schlaf zu töten (das heißt, wenn es ein Vordergrundprozess ist, ctrl-c tun wird).

Wenn wir Minuten oder Stunden Intervalle sprechen, wird Cron wahrscheinlich einen besseren Job machen, wie Montecristo darauf hingewiesen hat.

+0

Ich sehe .. Ich werde dieses versuchen. Danke Jungs! Ich lese besser "Mann Cron" auch dann. =) – Suezy

+0

Funktionsaufrufe sollten am Ende keine Parens haben. – camh

+0

absolut korrekt, nur die erklärung sollte, ich werde das ändern ... – falstro

5

Sie möchten vielleicht eine man cron tun.

Oder wenn Sie nur an Bash bleiben müssen, setzen Sie einfach den Funktionsaufruf innerhalb einer Schleife und Schlaf 60 innerhalb der Iteration.

0

Erstellen Sie ein Bash-Skript, das einmal überprüft, ob die Internetverbindung unterbrochen ist, und das Skript in eine crontab-Task einfügen, die alle 60 Sekunden ausgeführt wird.

4

Finden Sie hier ein Skript, das Sie verwenden können, Erster einen Beitrag für Ihre Cron-Job wie folgt hinzu:

$ sudo crontab -e * * * * */path/to/your/Switcher

Dies ist eine einfache Methode, die sich darauf konzentriert, jede Minute einen aktiven Server anzupingen, wenn der Server nicht erreichbar ist, wird er zum zweiten Router wechseln, der unten definiert ist.

sicherlich gibt es bessere Möglichkeit, dieses Problem auszunutzen.

$ cat> Switcher

#!/bin/sh 

route=`which route` 
ip=`which ip` 

# define your email here 
mail="[email protected]" 

# We define our pingable target like 'yahoo' or whatever, note that the host have to be 
# reachable every time 
target="www.yahoo.com" 

# log file 
file="/var/log/updown.log" 

# your routers here 
router1="192.168.0.1" 
router2="192.168.0.254" 

# default router 
default=$($ip route | awk '/default/ { print $3 }') 

# ping command 
ping -c 2 ${target} 

if [ $? -eq 0 ]; then 
    echo "`date +%Y%m%d-%H:%M:%S`: up" >> ${file} 

else 
    echo "`date +%Y%m%d-%H:%M:%S`: down" >> ${file} 

    if [ ${default}==${router1} ]; then 
     ${route} del default gw ${router1} 
     ${route} add default gw ${router2} 
    elif [ ${default}==${router2} ]; then 
     ${route} del default gw ${router2} 
     ${route} add default gw ${router1} 
    fi 
    # sending a notification by mail or may be by sms 
    echo "Connection problem" |mail -s "Changing Routing table" ${mail} 
fi 
+1

typo oben - sollte "sudo crontab -e ..." nicht "sudo contab -e ..." –

+0

Dies sieht aus wie die beste Lösung als Cron ist für diese Art von Aufgabe konzipiert.Tun Sie etwas (zB ein Skript) über eine wiederholbare Zeitverzögerung. – Jim

+0

Ich denke, dass das Skript den Standardrouter automatisch erkennt, aber denke, dass ich es gefunden habe –

1

Sie können wie die folgenden, etwas zu tun, aber es ist nicht zuverlässig:

 
#!/bin/sh 

trap handle_timer USR1 

set_timer() { (sleep 2; kill -USR1 $$)& } 
handle_timer() { 
    printf "%s:%s\n" "timer expired" "$(date)"; 
    set_timer 
} 

set_timer 
while true; do sleep 1; date; done 

Ein Problem bei dieser Technik besteht darin, dass der Fall nicht wirksam werden, bis Die aktuelle Aufgabe kehrt zur Shell zurück (z. B. den Schlaf 1 durch Schlaf 10 ersetzen). Wenn die Shell die meiste Zeit die Kontrolle hat (zB wenn alle aufgerufenen Befehle schnell beendet werden), kann dies funktionieren. Eine Möglichkeit ist natürlich, alles im Hintergrund laufen zu lassen.

3

Ich mochte Williams Antwort, weil es keine Abfrage benötigt. Also habe ich basierend auf seiner Idee das folgende Skript implementiert. Es funktioniert um das Problem herum, dass die Kontrolle zur Shell zurückkehren muss.

#!/bin/sh 

someproc() 
{ 
     sleep $1 
     return $2 
} 

run_or_timeout() 
{ 
     timeout=$1 
     shift 

     { 
       trap 'exit 0' 15 
       "[email protected]" 
     } & 
     proc=$! 

     trap "kill $proc" ALRM 
     { 
       trap 'exit 0' 15 
       sleep $timeout 
       kill -ALRM $$ 
     } & 
     alarm=$! 

     wait $proc 
     ret=$? 

     # cleanup 
     kill $alarm 
     trap - ALRM 
     return $ret 
} 

run_or_timeout 0 someproc 1 0 
echo "exit: $? (expected: 142)" 
run_or_timeout 1 someproc 0 0 
echo "exit: $? (expected: 0)" 
run_or_timeout 1 someproc 0 1 
echo "exit: $? (expected: 1)"