मैं एक क्रोन नौकरी कैसे बना सकता हूं जो हर तीन सप्ताह में एक कार्य चलाता है?


9

मेरे पास एक कार्य है जिसे मेरी परियोजना अनुसूची (3 सप्ताह) पर निष्पादित करने की आवश्यकता है।

मैं हर हफ्ते ऐसा करने के लिए क्रोन स्थापित करने में सक्षम हूं , या (उदाहरण के लिए) हर महीने के 3 वें सप्ताह पर - लेकिन हर तीन सप्ताह में ऐसा करने का तरीका नहीं मिल सकता है।

मैं अस्थायी फ़ाइलों (या इसी तरह) बनाने के लिए स्क्रिप्ट को हैक कर सकता था ताकि यह काम कर सके कि यह तीसरी बार चलाया गया है - लेकिन इस तरह से बदबू आ रही है।

क्या इसे साफ तरीके से किया जा सकता है?


@itj 3 सप्ताह = 21 दिन इसलिए हर 21 दिन में एक क्रोन कार्य क्यों नहीं किया जाता है?
स्टडर

1
@studer मुझे कुछ याद हो सकता है, लेकिन मुझे नहीं लगा कि crontab वह लचीला था
itj 22'10

जवाबों:


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 ))

और $ चेक वर्ष के 1, 4 वें, 7 वें, ... सप्ताह में 0 होगा।


3
वर्ष के अंत में क्या होता है? क्या यह अतिरिक्त समय चलेगा या एक सप्ताह या कुछ को छोड़ देगा, क्योंकि एक वर्ष 3 सप्ताह के एक से अधिक में विभाजित नहीं होता है?
davr

उत्तर के लिए धन्यवाद। मेरे पास किसी भी विचार की तुलना में निटर। इसका केवल 1 वर्ष ही मान्य है - लेकिन यह अधिकांश परियोजनाओं के लिए ठीक होना चाहिए।
itj

कई वर्षों में, आपको क्रिसमस और जनवरी 1 के आसपास 8 या 9 दिन के अंतराल पर दो रन मिलेंगे, इसलिए जब आपको इसे ठीक से करना होगा और "अंतिम रन डेट" को कहीं रिकॉर्ड करना होगा तो आप 3-सप्ताह की गणना कर सकते हैं। मध्यान्तर।
njd

3

पहले के उत्तर के लिए धन्यवाद, युगों के विकल्पों पर इंगित किया गया है-दिनांक या% s के रूप में स्वरूपण करने के लिए

यद्यपि थोड़ा सा दर्द ((date +%s) / 86400)युग से दिन देता है।

एक ही समय में चलाए जा रहे साप्ताहिक नौकरी पर भरोसा करते हुए, 3 सप्ताह की अवधि के एक विशिष्ट दिन ( $epoch_day%21 == 13उदाहरण के लिए) के खिलाफ यह जांचना आसान है

मेरे मामले में यह ठीक है, क्योंकि यह एक शॉट कार्य है। यदि यह किसी विशेष दिन से चूक जाता है तो अगले अवसर पर दौड़ने की कोई आवश्यकता नहीं है।


1

यदि आप रन के बीच टाइमस्टैम्प फ़ाइल को सहेज सकते हैं, तो आप केवल वर्तमान तिथि पर निर्भर होने के बजाय इसकी तिथि की जांच कर सकते हैं।

यदि आपकी खोज कमांड -mtime(या है -mmin) के लिए आंशिक मानों का समर्थन करती है ( GNU खोज में दोनों हैं , तो POSIX की आवश्यकता नहीं लगती है ), आप खोज और स्पर्श के साथ क्रोन नौकरियों को 'थ्रॉटल' कर सकते हैं ।

या, यदि आपके पास एक स्टेटमेंट है, जो फ़ाइल की तारीखों को "सेकंड के बाद से" के रूप में दिखाने का समर्थन करता है (जैसे कि ग्नू कोरुटिल्स से स्टेट , अन्य कार्यान्वयन भी), तो आप डेट , स्टेट और शेल के तुलना ऑपरेटरों का उपयोग करके अपनी खुद की तुलना कर सकते हैं (साथ में) एक टाइमस्टैम्प फ़ाइल को अद्यतन करने के लिए स्पर्श के साथ )। यदि आप स्वरूपण (जैसे GNU फ़ाइलल से ls ) कर सकते हैं, तो आप स्टेट के बजाय ls का उपयोग करने में सक्षम हो सकते हैं ।

नीचे एक पर्ल प्रोग्राम है (मैंने इसे बुलाया n-hours-ago) जो टाइमस्टैम्प फ़ाइल को अपडेट करता है और सफलतापूर्वक बाहर निकलता है अगर मूल टाइमस्टैम्प पर्याप्त पुराना था। इसके उपयोग पाठ से पता चलता है कि क्रोनब की प्रविष्टि में इसका उपयोग क्रोन जॉब के लिए कैसे किया जाता है। यह "दिन के उजाले की बचत" के समायोजन और पिछले रनों से 'देर' के टाइमस्टैम्प को कैसे प्रबंधित करता है, इसका भी वर्णन करता है।

#!/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;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.