2009-08-04 10 views
7

Dzień dobry! Czy istnieje jakiś sposób dołączenia do skryptu timera (znacznika czasu lub innego terminu) za pomocą bash? Na przykład; co 60 sekund określona funkcja sprawdza, czy internet nie działa, a jeśli jest, łączy się z urządzeniem Wi-Fi i na odwrót. W skrócie, program od czasu do czasu sprawdza połączenie internetowe.Jak uwzględnić timer w skryptach Bash?

Wszelkie sugestie/odpowiedzi będą mile widziane. =)

Odpowiedz

18

Blunt wersja

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

Korzystanie sen się jako warunek pętli pozwala wyrwać się z pętli zabijając snu (czyli czy jest to proces pierwszoplanowy, ctrl-c zrobi).

Jeśli mówimy w odstępach minutowych lub godzinowych, cron prawdopodobnie wykona lepszą robotę, jak zauważył Montecristo.

+0

Widzę .. Spróbuję tego. Dzięki chłopaki! Lepiej też przeczytać o "man cron". =) – Suezy

+0

wywołania funkcji nie powinny mieć parens na końcu. – camh

+0

absolutnie poprawne, tylko deklaracja powinna, zmienię to ... – falstro

5

Możesz chcieć zrobić człowiek cron.

Albo jeśli po prostu musisz trzymać się bash, po prostu wywołaj funkcję wewnątrz pętli i spać 60 wewnątrz iteracji.

0

Utwórz skrypt bash, który sprawdza raz, czy połączenie internetowe nie działa i dodaje skrypt do zadania crontab, które jest uruchamiane co 60 sekund.

4

Proszę tu skrypt, który można wykorzystać, należy najpierw dodać wpis do crona tak:

$ sudo crontab -e * * * * */ścieżka/do/pliku/przełącznik

To jest prosta metoda, która polega na ciągłym pingowaniu serwera żywego co minutę, jeśli serwer nie jest osiągalny, przełączy się na drugi router zdefiniowany poniżej.

Na pewno istnieje lepszy sposób na wykorzystanie tego problemu.

$ cat> przełącznik

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

literówka powyżej - powinna być "sudo crontab -e ..." a nie "sudo contab -e ..." –

+0

To wygląda jak najlepsze rozwiązanie jak cron jest przeznaczony do tego rodzaju zadań.Zrób coś (np. Skrypt) w pewnym powtarzalnym czasie. – Jim

+0

Myślę, że skrypt nie wykrywa automatycznie domyślnego routera, ale myślę, że go znalazłem –

1

można coś zrobić jak poniżej, ale to nie jest wiarygodne:

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

Jeden problem z tej techniki jest to, że pułapka nie będzie obowiązywać, dopóki bieżące zadanie powraca do powłoki (np. zamień uśpienie 1 na uśpienie 10). Jeśli powłoka ma kontrolę przez większość czasu (np. Jeśli wszystkie polecenia, które wywołają, szybko się zakończy), to może zadziałać. Jedną z opcji oczywiście jest uruchomienie wszystkiego w tle.

3

Podobała mi się odpowiedź Williama, ponieważ nie wymaga sondowania. Więc zaimplementowałem poniższy skrypt oparty na jego pomyśle. Rozwiązuje problem polegający na tym, że sterowanie musi powrócić do powłoki.

#!/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)" 
Powiązane problemy