Как включить таймер в Bash Scripting? - PullRequest
7 голосов
/ 04 августа 2009

Добрый день! Есть ли способ включить таймер (отметку времени? Или как-то еще) в сценарий, используя bash ? Как например; каждые 60 секунд определенная функция проверяет, не работает ли интернет, если он есть, то вместо этого он подключается к устройству Wi-Fi и наоборот. Одним словом, программа время от времени проверяет интернет-соединение.

Любые предложения / ответы будут высоко оценены. =)

Ответы [ 6 ]

18 голосов
/ 04 августа 2009

Тупая версия

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

Использование самого сна в качестве условия цикла позволяет вам выйти из цикла, убив сон (то есть, если это процесс переднего плана, ctrl-c сделает).

Если мы говорим с интервалами в минуты или часы, cron, вероятно, справится лучше, как указывал Монтекристо.

5 голосов
/ 04 августа 2009

Вы можете сделать man cron .

Или, если вам просто нужно придерживаться bash, просто поместите вызов функции внутри цикла и sleep 60 внутри итерации.

4 голосов
/ 04 августа 2009

Пожалуйста, найдите здесь скрипт, который вы можете использовать, сначала добавьте запись в вашу работу cron следующим образом:

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

Это простой метод, который заключается в непрерывной проверке работоспособного сервера каждую минуту, если сервер недоступен, он переключится на второй маршрутизатор, определенный ниже.

наверняка есть лучший способ использовать эту проблему.

$ cat> switcher

#!/bin/sh

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

# define your email here
mail="user@domain.tld"

# 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
3 голосов
/ 21 апреля 2011

Мне понравился ответ Уильяма, потому что он не нуждается в опросе. Поэтому я реализовал следующий скрипт на основе его идеи. Он работает вокруг проблемы, когда управление должно вернуться в оболочку.

#!/bin/sh

someproc()
{
        sleep $1
        return $2
}

run_or_timeout()
{
        timeout=$1
        shift

        {
                trap 'exit 0' 15
                "$@"
        } &
        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)"
1 голос
/ 04 августа 2009

Вы можете сделать что-то вроде следующего, но это ненадежно:

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

Одна из проблем этого метода заключается в том, что ловушка не вступит в силу, пока текущее задание не вернется в оболочку (например, замените sleep 1 на sleep 10). Если оболочка находится под контролем большую часть времени (например, если все команды, которые она вызывает, быстро завершатся), это может сработать. Один из вариантов, конечно, это запускать все в фоновом режиме.

0 голосов
/ 04 августа 2009

Создайте сценарий bash, который один раз проверяет, не работает ли интернет-соединение, и добавьте сценарий в задачу crontab, которая выполняется каждые 60 секунд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...