महीने के आखिरी दिन चलाने के लिए CRON जॉब


95

मुझे एक CRON जॉब बनाने की जरूरत है जो हर महीने के आखिरी दिन चलेगी। मैं इसे cPanel का उपयोग करके बनाऊंगा।

किसी भी मदद की सराहना की है। धन्यवाद

जवाबों:


180

संभवतः सबसे आसान तरीका तीन अलग-अलग काम करना है:

55 23 30 4,6,9,11        * myjob.sh
55 23 31 1,3,5,7,8,10,12 * myjob.sh
55 23 28 2               * myjob.sh

यह 28 फरवरी को चलेगा, हालांकि, लीप ईयर पर भी, अगर यह समस्या है, तो आपको एक और रास्ता तलाशना होगा।


हालांकि, यह आमतौर पर प्रत्येक महीने के पहले दिन जितनी जल्दी हो सके नौकरी चलाने के लिए काफी आसान और सही दोनों है , कुछ इस तरह से:

0 0 1 * * myjob.sh

और पिछले महीने के डेटा को संसाधित करने के लिए स्क्रिप्ट को संशोधित करें ।

यह किसी भी परेशानी को हटाता है जो आपको पता लगा सकता है कि महीने का आखिरी दिन कौन सा है, और यह भी सुनिश्चित करता है कि उस महीने के सभी डेटा उपलब्ध हैं, यह मानते हुए कि आप डेटा संसाधित कर रहे हैं। महीने के आखिरी दिन पांच मिनट से आधी रात तक चलने से आपको कुछ भी याद आ सकता है जो तब और आधी रात के बीच होता है।

यह वैसे भी करने का सामान्य तरीका है, सबसे अंत महीने की नौकरियों के लिए।


अगर आप अभी भी वास्तव में महीने के अंतिम दिन पर इसे चलाने के लिए चाहते हैं, एक ही विकल्प बस अगर कल (अपनी स्क्रिप्ट के हिस्से के रूप में या तो, या crontab अपने आप में) पहला है पता लगाने के लिए है।

तो, कुछ इस तरह:

55 23 28-31 * * [[ "$(date --date=tomorrow +\%d)" == "01" ]] && myjob.sh

एक अच्छी शुरुआत होनी चाहिए, यह मानते हुए कि आपके पास अपेक्षाकृत बुद्धिमान dateकार्यक्रम है।

यदि आपका dateकार्यक्रम आपको सापेक्ष तिथियां देने के लिए पर्याप्त रूप से उन्नत नहीं है, तो आप बस महीने के कल (आप को पूर्ण शक्ति की आवश्यकता नहीं है date) देने के लिए एक बहुत ही सरल कार्यक्रम एक साथ रख सकते हैं , जैसे:

#include <stdio.h>
#include <time.h>

int main (void) {
    // Get today, somewhere around midday (no DST issues).

    time_t noonish = time (0);
    struct tm *localtm = localtime (&noonish);
    localtm->tm_hour = 12;

    // Add one day (86,400 seconds).

    noonish = mktime (localtm) + 86400;
    localtm = localtime (&noonish);

    // Output just day of month.

    printf ("%d\n", localtm->tm_mday);

    return 0;
}

और फिर उपयोग करें (यह मानकर कि आपने इसे tomdom"महीने के कल के लिए बुलाया है "):

55 23 28-31 * * [[ "$(tomdom)" == "1" ]] && myjob.sh

यद्यपि आप दोनों के बाद से त्रुटि जाँच को जोड़ने पर विचार कर सकते हैं time()और यदि कुछ गलत होता है तो mktime()वापस आ सकते -1हैं। सरलता के कारणों के लिए उपरोक्त कोड, इसे ध्यान में नहीं रखता है।


7
हाँ, यह अंतिम दिन के बजाय हर पहले दिन पर चलना आसान हो सकता है :)
उत्तुम दलमाज

1
महीने का पहला दिन वास्तव में। यहां बताया गया है कि PHP $ date = new DateTime ('2013-03-01') में कैसा दिखेगा; $ तारीख-> संशोधित ('- 1 महीना'); $ पूर्ववर्ती = $ तिथि-> प्रारूप ('Y-m'); // $ पिछलामाउथ अब 2013-02 है। पिछले महीने के लिए उत्पादों को लाने के लिए क्वेरी बनाएँ।
लैमी

लीप वर्ष feb 29 डेटा खो जाएगा, हमें उस पर भी विचार करने की आवश्यकता है। नीचे दिए गए थंडर रैबिट उत्तर पर विचार करते हैं, लेकिन क्रोन लीप वर्ष में दो बार दौड़ते हैं
हरि स्वामीनाथन

1
@ हरि, पसंदीदा समाधान महीने के पहले भाग पर चलना होगा और पिछले महीने के आंकड़ों को इकट्ठा करना होगा। 29 फरवरी को उस मामले में याद नहीं किया जाएगा।
paxdiablo

1
लीप
ईयर को

52

थोड़ी कम विधि है जो ऊपर दिए गए एक के समान उपयोग की जा सकती है। अर्थात्:

[ $(date -d +1day +%d) -eq 1 ] && echo "last day of month"

इसके अलावा, crontab प्रविष्टि केवल 28 वें से 31 वें दिन जांचने के लिए अद्यतन की जा सकती है क्योंकि यह महीने के अन्य दिनों में इसे चलाने में व्यर्थ है। जो आपको देगा:

0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh

मैं इसे एक कॉन्टैब एंट्री के रूप में काम करने के लिए नहीं मिला (कुछ मुझे लगता है कि बच निकलने की जरूरत है)। यह एक पटकथा में अच्छी तरह से काम करता था जिसे कॉट्रैब कहा जाता था। FYI करें, मुझे जो त्रुटि मिली वह थी /bin/sh: -c: line 1: unexpected EOF while looking for matching ')'
मार्क राजकोक

13
यह बहुत अच्छा काम करता है। Crontab फ़ाइल में% बच जाना चाहिए। तो[ $(date -d +1day +\%d) -eq 1 ] && run_job
कॉलिनएम

अच्छी चाल वास्तव में! लेकिन सवाल का टैग posix"-d +1day"[ `date +\%d` -eq `cal | xargs echo | awk '{print $NF}'` ] && myscript.sh
लगाया

18

महीने के पहले दिन चलाने के लिए क्रॉन जॉब सेट करें। फिर सिस्टम की घड़ी को एक दिन पहले बदल दें।


10
जिसका अर्थ है कि सिस्टम घड़ी हर समय गलत होगी। क्षमा करें, लेकिन मुझे लगता है कि यह अधिक समस्या का कारण होगा। -1 फिर।
रूडी

69
अब मुझे पता है कि गैलीलियो को कैसा लगा।
टॉम एंडरसन

7
@ डायनोकॉस्ट: मैं इसे कोक से ज्यादा एक मजाक के रूप में सोचना चाहूंगा।
टॉम एंडरसन

14
मुझे लगता है कि यह वास्तव में बुरा और शानदार विचार है। घर पर ऐसा मत करो, बच्चों।
पास्कल

11
@pascalbetz ओह, लोग इसे घर पर कर सकते हैं, लेकिन उन्हें वास्तव में काम नहीं करना चाहिए।
टॉम एंडरसन

14

विकिपीडिया के बाद इस बारे में क्या?

55 23 L * * /full/path/to/command

खैर, इसका क्या? वह: "crontab फ़ाइल में महीने की खराब त्रुटियां, इंस्टॉल नहीं हो सकती हैं। क्या आप उसी संपादन को फिर से करना चाहते हैं?"
वेबजंकली

12
बस स्पष्ट होने के लिए, विकिपीडिया प्रविष्टि में यह भी उल्लेख है कि "एल" गैर-मानक है।
sdupton

10

पैक्सिडाब्लो के समाधान का पालन करते हुए, मैं 28 और 29 फरवरी को चलता हूं । 29 वें से डेटा 28 वें ओवरराइट करता है।

# min  hr  date     month          dow
  55   23  31     1,3,5,7,8,10,12   * /path/monthly_copy_data.sh
  55   23  30     4,6,9,11          * /path/monthly_copy_data.sh
  55   23  28,29  2                 * /path/monthly_copy_data.sh

4
जब तक, निश्चित रूप से, नौकरी में कुछ विनाशकारी पहलू है जैसे कि यह संसाधित होने पर सभी डेटा को साफ़ करना है :-)
paxdiablo

यह वास्तव में एक दर्द रहित विकल्प (कम से कम तकनीकी) है, और हो सकता है कि आप 4 साल में तीन बार इस बात की परवाह न करें कि आप क्रोनजॉब बहुत जल्दी प्राप्त कर लेंगे यदि आप बस छोड़ देते हैं ,29
मैट

@ मैट: उम्म, क्या आपका मतलब यह नहीं है कि यह चार साल में एक बार बहुत जल्दी चलेगा अगर आपका कॉन्टैब एंट्री कहे 55   23   28    2?
जी-मैन का कहना है कि 'मोनिका' की बहाली

@ जी-मैन हाँ, आप सही कह रहे हैं, और उसके ऊपर, आपने इसे 29 वीं बार दूसरी बार चलाया है।
मैट

8

आप महीने के हर दिन चलने के लिए क्रोन जॉब सेट कर सकते हैं, और इसमें निम्नलिखित की तरह एक शेल स्क्रिप्ट भी चल सकती है। यह स्क्रिप्ट काम करती है कि क्या कल का दिन संख्या आज से कम है (यानी यदि कल एक नया महीना है), और फिर आप जो चाहें करें।

TODAY=`date +%d`
TOMORROW=`date +%d -d "1 day"`

# See if tomorrow's day is less than today's
if [ $TOMORROW -lt $TODAY ]; then
echo "This is the last day of the month"
# Do stuff...
fi

मुझे यकीन नहीं है कि अगर आप आज की तुलना में कम है, तो आप यह जांच कर सकते हैं - अगर यह 1 है तो आपको बस जांच करने में सक्षम होना चाहिए। जब तक कि महीने का पहला दिन 2nd या 3rd :-) न हो
paxdiablo

7

@Indie समाधान के आधार पर क्रॉस्टेब में एक सुरक्षित विधि के लिए (संपूर्ण मार्ग का उपयोग करें date+ $()सभी क्रोस सिस्टम पर काम नहीं करता है):

0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh

6

कुछ क्रोन कार्यान्वयन महीने के अंतिम दिन का प्रतिनिधित्व करने के लिए "एल" ध्वज का समर्थन करते हैं।

यदि आप उन कार्यान्वयनों में से एक का उपयोग करने के लिए भाग्यशाली हैं, तो यह उतना ही सरल है:

0 55 23 L * ?

जो कि हर महीने के आखिरी दिन 11:55 बजे चलेगा।

http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger


5
#########################################################
# Memory Aid 
# environment    HOME=$HOME SHELL=$SHELL LOGNAME=$LOGNAME PATH=$PATH
#########################################################
#
# string         meaning
# ------         -------
# @reboot        Run once, at startup.
# @yearly        Run once a year, "0 0 1 1 *".
# @annually      (same as @yearly)
# @monthly       Run once a month, "0 0 1 * *".
# @weekly        Run once a week, "0 0 * * 0".
# @daily         Run once a day, "0 0 * * *".
# @midnight      (same as @daily)
# @hourly        Run once an hour, "0 * * * *".
#mm     hh      Mday    Mon     Dow     CMD # minute, hour, month-day month DayofW CMD
#........................................Minute of the hour
#|      .................................Hour in the day (0..23)
#|      |       .........................Day of month, 1..31 (mon,tue,wed)
#|      |       |       .................Month (1.12) Jan, Feb.. Dec
#|      |       |       |        ........day of the week 0-6  7==0
#|      |       |       |        |      |command to be executed
#V      V       V       V        V      V
*       *       28-31   *       *       [ `date -d +'1 day' +\%d` -eq 1 ] && echo "Tomorrow is the first today now is  `date`" >> ~/message
1       0       1       *       *       rm -f ~/message
*       *       28-31   *       *       [ `date -d +'1 day' +\%d` -eq 1 ] && echo "HOME=$HOME LOGNAME=$LOGNAME SHELL = $SHELL PATH=$PATH" 

5

एडब्ल्यूएस क्लाउडवॉच क्रॉन कार्यान्वयन (शेड्यूलिंग लैम्ब्डा, आदि) के लिए यह काम करता है:

55 23 L * ? *

प्रत्येक माह के अंतिम दिन 11:55 बजे चलेंगे।



3

आप केवल एक क्रोन लाइन में सभी उत्तरों को जोड़ सकते हैं और केवल dateकमांड का उपयोग कर सकते हैं ।

बस महीने के दिन के बीच अंतर की जांच करें जो आज है और कल होगा:

0 23 * * * root [ $(expr $(date +\%d -d '1 days') - $(date +\%d)  ) -le 0 ]  && echo true

यदि ये अंतर 0 से नीचे है तो इसका मतलब है कि हम महीने को बदलते हैं और महीने का आखिरी दिन होता है।


3
55 23 28-31 * * echo "[ $(date -d +1day +%d) -eq 1 ] && my.sh" | /bin/bash 

1
कमांड को इको करना और क्रॉन के साथ काम करते समय इसे बैश में पाइप करना सबसे अच्छा तरीका है। चूंकि क्रोन श का उपयोग कर रहा है और बैश का नहीं। जांचें कि आपका बैश 'किस बैश' का उपयोग कर रहा है। फ्रीबीएसडी पर यह लिनक्स / बिन / बैश पर / usr / स्थानीय / बिन / बैश है।
डोनाल्ड डक

2

इस बारे में क्या?

उपयोगकर्ता का संपादन संपादित करें .bashprofile:

export LAST_DAY_OF_MONTH=$(cal | awk '!/^$/{ print $NF }' | tail -1)

फिर इस प्रविष्टि को crontab में जोड़ें:

mm hh * * 1-7 [[ $(date +'%d') -eq $LAST_DAY_OF_MONTH ]] && /absolutepath/myscript.sh

0

महीने का अंतिम दिन 28-31 हो सकता है जो इस बात पर निर्भर करता है कि यह किस महीने (फरवरी, मार्च आदि) है। हालाँकि, इन दोनों मामलों में, अगले दिन हमेशा अगले महीने की 1 तारीख होती है। इसलिए हम यह सुनिश्चित कर सकते हैं कि हम नीचे दिए गए कोड का उपयोग करके महीने के अंतिम दिन हमेशा कुछ काम चलाएं:

0 8 28-31 * * [ "$(date +%d -d tomorrow)" = "01" ] && /your/script.sh
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.