Как включить таймер в сценарии Bash?
Добрый день! Есть ли способ включить таймер (отметку времени?или какой бы то ни было термин) в скрипте, использующем Баш? Например, каждые 60 секунд определенная функция проверяет, отключен ли интернет, если он есть, то он подключается к устройству wifi вместо этого и наоборот. Короче говоря, программа Время от времени проверяет подключение к интернету.
любые предложения / ответы будут высоко оценены. =)
6 ответов
тупые версии
while sleep 60; do
if ! check_internet; then
if is_wifi; then
set_wired
else
set_wifi
fi
fi
done
использование самого сна в качестве условия цикла позволяет вырваться из цикла, убив сон (т. е. если это процесс переднего плана, ctrl-c будет делать).
Если мы говорим о минутах или часах интервалов, cron, вероятно, сделает лучшую работу, как отметил Монтекристо.
вы можете сделать человек cron.
или если вам просто нужно придерживаться bash, просто поместите вызов функции внутри цикла и спать 60 внутри итерации.
пожалуйста, найдите здесь скрипт, который вы можете использовать, сначала добавьте запись в задание cron следующим образом:
$ sudo crontab-e * * * * * * / path/to/your / switcher
Это простой метод, который находится на pinging живой сервер непрерывно каждую минуту, если сервер не доступен, он переключится на второй маршрутизатор, определенный ниже.
конечно, есть лучший способ, чтобы использовать эту проблему.
$ 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 }')
# 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
Мне понравился ответ Уильяма, потому что он не нужен опрос. Поэтому я реализовал следующий сценарий, основанный на его идее. Он работает вокруг проблемы, что элемент управления должен вернуться в оболочку.
#!/bin/sh
someproc()
{
sleep
return
}
run_or_timeout()
{
timeout=
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)"
вы можете сделать что-то вроде следующего, но это не надежно:
#!/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). Если оболочка находится под контролем большую часть времени (например, если все команды, которые она вызывает, быстро завершатся), это может работать. Один из вариантов, конечно, это запустить все в фоновом режиме.
создайте сценарий bash, который проверяет, отключено ли подключение к интернету, и добавьте сценарий в задачу crontab, которая выполняется каждые 60 секунд.