3週間ごとにタスクを実行するクーロン・ジョブを作成する方法を教えてください。


9

私は自分のプロジェクトスケジュール(3週間)で実行する必要があるタスクを持っています。

設定できます クーロン 毎週、または(たとえば)毎月3週目にこれを実行するには - しかし、3週間ごとにこれを実行する方法を見つけることができません。

一時ファイル(または類似のファイル)を作成するスクリプトをハッキングして、実行されたのが3回目であることが判明する可能性がありますが、この解決策は匂いがします。

クリーンな方法でそれをすることができますか?


@itj 3週間= 21日なので、21日ごとにクーロン・タスクを配置しないのはなぜですか?
Studer

1
@ studer私は何かを逃したかもしれませんが、私はcrontabがそれほど柔軟ではなかったと思いました
itj

回答:


8

crontabファイルでは、次のものだけを指定できます。

minute (0-59)
hour (0-23)
day of the month (1-31)
month of the year (1-12)
day of the week (0-6 with 0=Sunday)

そのため、どの週を適用するかを指定することは不可能です。

ラッパースクリプトを書くことが最善の選択肢かもしれません。
次のようにして、シェルスクリプトで週番号を取得できます。

date +%U

または

date +%V

あなたの週が日曜日に開始するのが好きか月曜日に開始するのかによって異なります。
だからあなたは使用することができます

week=$(date +%V)
check=$(( ($week - 1) % 3 ))

そして$ checkは、その年の1、4、7、...週で0になります。


3
年末にはどうなりますか?年は3週間の倍数に均等に分割されないので、それは余分な時間を実行するか、1週間か何かをスキップするでしょうか?
davr

ご回答ありがとうございます。私が持っていたどんな考えよりもいい。 1年間有効ですが、ほとんどのプロジェクトでは問題ありません。
itj

何年にもわたって、クリスマスの前後8〜9日の間隔で2回走ることになります。 1月1日です。そのため、3週間の間隔を計算できるように、正しく実行して「最終実行日」をどこかに記録する必要があります。
njd

3

以前の回答のおかげで、今日までのエポックオプションが指摘されています -eまたは%sとしてフォーマット

少し痛いですが ((date +%s) / 86400) エポックからの日数を与えます。

同時に実行されている毎週のジョブに頼って、3週間の期間の特定の日に対してこれをチェックすることは簡単です $epoch_day%21 == 13 例えば)

私の場合、これは大丈夫です、それはワンショットのタスクなので。それが特定の日に逃されるならば、それから次の機会に走る必要はありません。


1

実行間のタイムスタンプファイルを保存できる場合は、現在の日付だけに頼るのではなく、その日付を確認できます。

もしあなたの 見つける コマンドは以下の小数値をサポートします。 -mtime (または -mmin )( GNU findには両方があります POSIXも必要ないようです )で、cronジョブを「調整」できます。 見つける そして タッチ

または、持っていれば 統計 ファイルの日付を「エポックからの秒数」として表示することをサポートするコマンド(例: 統計 Gnu coreutilsから (他の実装も)、あなたはあなた自身の比較をすることができます 日付 統計 、およびシェルの比較演算子(とともに) タッチ タイムスタンプファイルを更新します。あなたも使うことができるかもしれません ls の代わりに 統計 フォーマットが可能な場合(例: GNU fileutilsからのls

以下はPerlプログラムです(私はそれを呼びました n-hours-ago これはタイムスタンプファイルを更新し、元のタイムスタンプが十分古かった場合は正常に終了します。その用法テキストは、cronジョブを抑制するためにcrontabエントリーでそれを使用する方法を示しています。また、「夏時間」の調整と前回の実行からの「遅い」タイムスタンプの処理方法についても説明します。

#!/usr/bin/perl
use warnings;
use strict;
sub usage {
    printf STDERR <<EOU, $0;
usage: %s <hours> <file>

    If entry at pathname <file> was modified at least <hours> hours
    ago, update its modification time and exit with an exit code of
    0. Otherwise exit with a non-zero exit code.

    This command can be used to throttle crontab entries to periods
    that are not directly supported by cron.

        34 2 * * * /path/to/n-hours-ago 502.9 /path/to/timestamp && command

    If the period between checks is more than one "day", you might
    want to decrease your <hours> by 1 to account for short "days"
    due "daylight savings". As long as you only attempt to run it at
    most once an hour the adjustment will not affect your schedule.

    If there is a chance that the last successful run might have
    been launched later "than usual" (maybe due to high system
    load), you might want to decrease your <hours> a bit more.
    Subtract 0.1 to account for up to 6m delay. Subtract 0.02 to
    account for up to 1m12s delay. If you want "every other day" you
    might use <hours> of 47.9 or 47.98 instead of 48.

    You will want to combine the two reductions to accomodate the
    situation where the previous successful run was delayed a bit,
    it occured before a "jump forward" event, and the current date
    is after the "jump forward" event.

EOU
}

if (@ARGV != 2) { usage; die "incorrect number of arguments" }
my $hours = shift;
my $file = shift;

if (-e $file) {
    exit 1 if ((-M $file) * 24 < $hours);
} else {
    open my $fh, '>', $file or die "unable to create $file";
    close $fh;
}
utime undef, undef, $file or die "unable to update timestamp of $file";
exit 0;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.