ฉันจะสร้างงาน cron ที่ทำงานได้ทุกสามสัปดาห์ได้อย่างไร


9

ฉันมีงานที่ต้องทำตามกำหนดเวลาโครงการ (3 สัปดาห์)

ฉันสามารถตั้งค่าcronให้ทำเช่นนี้ทุกสัปดาห์หรือ (ตัวอย่าง) ในสัปดาห์ที่ 3 ของทุกเดือน - แต่ไม่สามารถหาวิธีทำเช่นนี้ได้ทุกสามสัปดาห์

ฉันสามารถแฮกสคริปต์เพื่อสร้างไฟล์ชั่วคราว (หรือคล้ายกัน) เพื่อให้สามารถทำงานได้เป็นครั้งที่สามที่มีการเรียกใช้ - แต่วิธีนี้มีกลิ่น

สามารถทำได้ด้วยวิธีที่สะอาดหรือไม่?


@itj 3 สัปดาห์ = 21 วันดังนั้นทำไมไม่ทำภารกิจ cron ทุก ๆ 21 วัน?
Studer

1
@studer ฉันอาจจะพลาดอะไรบางอย่าง แต่ฉันไม่คิดว่า crontab ยืดหยุ่นดี
เท่าไหร่

คำตอบ:


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 จะเป็น 0 ในสัปดาห์ที่ 1, 4, 7, ...


3
จะเกิดอะไรขึ้นในช่วงปลายปี มันจะใช้เวลาเพิ่มหรือข้ามสัปดาห์หรือบางสิ่งบางอย่างเนื่องจากหนึ่งปีไม่แบ่งเท่า ๆ กันเป็น 3 สัปดาห์หรือไม่
davr

ขอบคุณสำหรับคำตอบ. น้อยกว่าความคิดที่ฉันมี มันใช้ได้เพียง 1 ปี - แต่มันก็น่าจะพอใช้สำหรับโครงการส่วนใหญ่
itj

ในช่วงหลายปีที่ผ่านมาคุณจะได้วิ่งสองระยะห่างกัน 8 หรือ 9 วันในช่วงคริสต์มาสและวันที่ 1 มกราคมดังนั้นเมื่อคุณต้องการทำอย่างถูกต้องและบันทึก "วันที่ดำเนินการล่าสุด" ที่ใดที่หนึ่งเพื่อให้คุณสามารถคำนวณ 3 สัปดาห์ ระยะห่าง
njd

3

ขอบคุณคำตอบก่อนหน้านี้ชี้ไปที่ตัวเลือกยุควันที่ -e หรือการจัดรูปแบบเป็น% s

แม้ว่าความเจ็บปวดเล็กน้อย((date +%s) / 86400)ให้วันจากยุค

การใช้งานรายสัปดาห์ที่กำลังดำเนินการอยู่ในเวลาเดียวกันนั้นจะง่ายต่อการตรวจสอบกับวันที่เฉพาะเจาะจงของระยะเวลา 3 สัปดาห์ ( $epoch_day%21 == 13เช่น)

ในกรณีของฉันนี้เป็นเรื่องปกติเพราะมันเป็นงานยิง หากพลาดในวันนั้น ๆ ก็ไม่จำเป็นต้องวิ่งในโอกาสต่อไป


1

หากคุณสามารถบันทึกไฟล์บันทึกเวลาระหว่างการทำงานคุณสามารถตรวจสอบวันที่ของไฟล์แทนการใช้ไฟล์วันที่ปัจจุบันเท่านั้น

หากคุณพบว่าคำสั่งสนับสนุนค่าเศษส่วนสำหรับ-mtime(หรือมี-mmin) ( GNU พบได้ทั้ง , POSIX ดูเหมือนจะไม่จำเป็นต้องใช้อย่างใดอย่างหนึ่ง ) คุณสามารถ 'เค้น' งาน cron กับที่มีการค้นพบและสัมผัส

หรือหากคุณมีสถิติคำสั่งที่สนับสนุนการแสดงวันที่ไฟล์เป็น“วินาทีตั้งแต่ยุค” (เช่นสถิติจาก coreutils Gnuยังใช้งานอื่น ๆ ) คุณสามารถทำให้การเปรียบเทียบของคุณเองโดยใช้วัน , สถิติและดำเนินการเปรียบเทียบของเปลือก (พร้อม ด้วยการแตะเพื่ออัปเดตไฟล์เวลาประทับ) คุณอาจสามารถใช้lsแทนstat ได้ถ้ามันสามารถทำการฟอร์แมต (เช่นls จาก GNU fileutils )

ด้านล่างเป็นโปรแกรม Perl (ฉันเรียกมันว่าn-hours-ago) ซึ่งอัปเดตไฟล์การประทับเวลาและออกสำเร็จหากการประทับเวลาดั้งเดิมนั้นเก่าพอ ข้อความการใช้งานแสดงวิธีใช้ในรายการ crontab เพื่อเร่งงาน cron นอกจากนี้ยังอธิบายการปรับสำหรับ "การประหยัดเวลากลางวัน" และวิธีจัดการกับการประทับเวลา 'ล่าช้า' จากการวิ่งครั้งก่อน

#!/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.