如何模拟一个cron作业

时间:2010-08-20 17:17:06

标签: perl bash scripting cron

我希望每天运行一个脚本(并且只在周末运行),但是,我不能使用cron作业。

我正在考虑进行无限循环,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 个答案:

答案 0 :(得分:11)

在没有每用户crontabs的那天,我经常使用(1)完成此操作。

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

这样,您的脚本就会运行并为下次调用安排自己。

我认为你不能指定“下周末”的时间规格,所以你只需要每天重新安排并让你的脚本退出(如果不是周末就退出工作岗位)。 / p>

编辑:或者不是每天都安排,而是找出今天的情况并做好相应的安排。 e.g。

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

如果这个脚本在星期六运行,它会安排下一个星期日的下一次运行,否则它将在下周六运行。 [ $(date +%A) = Saturday ]可能更具可读性,但%A将提供特定于语言环境的字符串,因此如果更改语言环境,则可能无效。

答案 1 :(得分: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();

答案 2 :(得分: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

答案 3 :(得分:1)

假设你真的不能使用cron或at来安排工作,你需要编写一个睡眠循环。您编写它的详细信息将根据您的要求而有所不同。

如果您只想每天执行一次,您必须担心短暂的睡眠。大多数语言睡眠功能下面的睡眠系统调用并不能保证它会在请求的时间内睡眠。您的程序可能会比请求的时间稍长或比请求的时间短。您可以安排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

答案 4 :(得分:0)

您可以使用snaked。它类似于cron,但用Perl编写。