Как смоделировать работу cron - PullRequest
12 голосов
/ 20 августа 2010

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

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

Что это хорошее решение под Bash на 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 ]

11 голосов
/ 21 августа 2010

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

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

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

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

Редактировать: Или вместо того, чтобы планировать каждый день, выясните, что сегодня такое, и составьте соответствующее расписание. например, * +1008 *

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

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

5 голосов
/ 20 августа 2010

Для решения 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();
1 голос
/ 20 августа 2010

Если вы действительно не можете использовать cron или at для планирования заданий, вам нужно написать цикл ожидания. Детали того, как вы пишете, зависят от ваших требований.

Если вы хотите выполнять только один раз в день, вам нужно беспокоиться о коротких снах. Системный вызов sleep, который находится под большинством языков, не гарантирует, что он будет спать в течение требуемого промежутка времени. Ваша программа может спать немного дольше, чем запрошено, или намного короче, чем запрошено. Вы можете запланировать режим сна на 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
1 голос
/ 20 августа 2010

Проблема с использованием длинного 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 голосов
/ 21 августа 2010

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

...