2010-08-20 4 views
12

Я хочу запустить сценарий один раз в день (и только по выходным дням), однако я не могу использовать для этого работу cron.Как имитировать задачу cron

Я думал о том, чтобы иметь бесконечный цикл while, спать в течение 24 часов, проверять, есть ли уик-энд, и если так выполнить сценарий.

Что такое хорошее решение под bash on linux?

моя текущая реализация:

#! /bin/bash 

while [ true ]; do 
    if [[ $(date +%u) -lt 6 ]]; then 
       ./program 
     else 
      echo Today is a weekend, processing is skipped. Back to sleep. 
    fi 
    sleep 86400 
done 

И запустит этот скрипт в 5 часов вечера.

+5

cron - хорошее решение. Можете ли вы рассказать нам, почему вы не можете его использовать? – haydenmuhl

+0

Не могли бы вы уточнить свои ограничения? Работа «на» не приемлема? Должно ли перезагрузка автоматически после перезагрузки сервера? – extraneon

+0

У меня нет разрешений на использование cron-таблиц. Предположим, что сервер НЕ перезагрузится. – vehomzzz

ответ

11

В тот день, когда не было пользователей perront, я часто делал это с использованием (1).

#!/bin/sh 
... do stuff... 
at -f /path/to/me 5pm tomorrow 

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

Я не думаю, что вы можете указать спецификацию «на следующий уик-энд», так что вам просто нужно будет перепланировать каждый день и выйти из своего сценария (после планирования следующего на задании), если это не выходные.

Редактировать: Или вместо планирования каждый день узнайте, что сегодня такое и планируете. например

day=Saturday 
if [ $(date +%u) -eq 6 ] ; then day=Sunday ; fi 
at -f /path/to/me 5pm next $day 

Если этот скрипт запускается на субботу, она планирует следующий запуск в ближайшее воскресенье, в противном случае она проходит в следующую субботу. [ $(date +%A) = Saturday ] может быть более читаемым, buts% A даст строку, специфичную для локали, поэтому может не работать, если вы меняете язык.

1

Проблема с использованием длинного sleep заключается в том, что идея вашей программы о том, во сколько времени она будет дрейфовать. Было бы лучше просто зациклиться с короткими периодами sleep и проверить, находитесь ли вы в нужном окне.

Если ваши администраторы не позволяют вам использовать cron, они могут быть недовольны тем, что вы обошли это ограничение.

Однако, здесь грубый набросок:

while : 
do 
    dow=$(date +%u) 
    if ((dow == 6 || dow == 7)) 
    # you can check a flag or counter to limit the number of times it's performed 
    # or use a more refined date spec than just whole days (times of day, in other words) 
    then 
     do_something 
     sleep 1h # or use a smaller or larger interval 
    fi 
done 
+0

Ваш выход do_something по крайней мере 24 раза в день по выходным. Постоянный сон в течение 24 часов не будет работать, потому что сон может вернуться раньше. –

+0

это в значительной степени то, что я придумал. Я отправлю его в оригинальном вопросе – vehomzzz

1

Предполагая, что вы действительно не можете использовать хрон или планировать выполнение заданий вам нужно будет написать цикл сна. Информация о том, как вы его пишете, будет зависеть от ваших требований.

Если вы хотите только один раз в день, вам придется беспокоиться о коротких сна. Системный вызов сна, находящийся под большинством функций сна, не гарантирует, что он будет спать запрошенный промежуток времени. Ваша программа может спать немного дольше, чем требуется, или намного меньше запрошенной. Вы можете запланировать спящий режим в течение 24 часов, но ОС может разбудить вашу программу, чтобы доставить сигнал через несколько часов или даже через несколько секунд. Если вы не отслеживаете последний прогон или ваш следующий ожидаемый прогон, вы можете выполнять несколько раз в день.

Если вы хотите выполнить в определенное время, вам потребуется изменить продолжительность сна. Частичный сон может отключить вас на полдня, и вам нужно будет спать 12 часов, чтобы вернуться в синхронизацию.

Вам необходимо учитывать Летнее время/Летнее время. Один день в году будет 23 часов, а другой будет 25.

Вы можете использовать что-то вдоль линий этого псевдокода:

set next_time_to_run 
loop forever 
    sleep time_difference_in_seconds(current_time, next_time_to_run) 
    if current_time is close to next_time_to_run 
     execute code 
     update next_time_to_run 
    end if 
end loop 
5

Для решения Perl, то посмотрите на Schedule::Cron модуль CPAN:

use 5.012; 
use warnings; 
use Schedule::Cron; 

my $cron = Schedule::Cron->new(sub {}); 

# add weekend run @ 05:00 
$cron->add_entry('0 5 * * Sat,Sun', sub { 
    system './program'; 
}); 

$cron->run(); 
0

Вы можете использовать snaked. Он похож на cron, но написан на Perl.

Смежные вопросы