EQVPS

VPS पर cron और systemd टाइमर से टास्क शेड्यूल कैसे करें

बैकअप, सफ़ाई और स्क्रिप्ट शेड्यूल पर चलाएँ। पाँच मिनट में cron और वे तीन जाल जो चुपचाप टास्क तोड़ देते हैं, फिर लॉग, बंद रहने के बाद छूटे रन पूरे करने और सटीक समय के लिए systemd टाइमर। नीचे का हर व्यवहार नए Ubuntu 24.04 सर्वर पर परखा गया।

सर्वर अपनी क़ीमत तब वसूलता है जब आपके सोते समय काम करे: बैकअप, लॉग रोटेशन, सर्टिफ़िकेट नवीनीकरण, नौ बजे की रिपोर्ट। Linux में इसके लिए दो शेड्यूलर हैं। cron चालीस साल पुराना है और एक लाइन काफ़ी है। systemd टाइमर को दो छोटी फ़ाइलें चाहिए, और बदले में लॉग, बंद रहने के बाद छूटे रन की भरपाई और सटीक समय मिलता है। यह गाइड Ubuntu 24.04 पर दोनों को समझाती है, और हर व्यवहार हमारी इमेज से बने नए सर्वर पर जाँचा गया है, उन तीन गलतियों समेत जिनसे cron टास्क बिना एक शब्द कहे फ़ेल हो जाता है।

आपको sudo वाला यूज़र चाहिए; Ubuntu सेटअप गाइड एक बनाती है।

1. पाँच मिनट में cron

cron हमारी Ubuntu और Debian इमेज पर इंस्टॉल है और चल रहा है। हर यूज़र की अपनी टास्क टेबल होती है; अपनी टेबल इससे एडिट करें:

crontab -e

हर लाइन में पाँच समय फ़ील्ड और एक कमांड होती है:

# min hour day month weekday  command
  30  3    *   *     *        /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
  */5 *    *   *     *        /usr/local/bin/check.sh
  0   9    *   *     1-5      /usr/local/bin/report.sh
  @reboot                     /usr/local/bin/start-tunnel.sh

यानी: हर रात 03:30 पर, हर 5 मिनट में, कामकाजी दिनों में 09:00 पर, और हर बूट के बाद एक बार। */5 का मतलब हर पाँचवाँ मान, 1-5 एक रेंज, 1,15 एक सूची। सर्वर का टाइम ज़ोन लागू होता है, हमारी इमेज पर UTC; अपना ज़ोन एक बार होस्टनेम और टाइम ज़ोन गाइड से सेट करें और cron उसी पर चलेगा।

जो चला उसे journalctl -u cron से देखें। हर रन यूज़र और कमांड लॉग करता है, और वहीं तीनों जाल दिखते हैं।

जाल 1: आउटपुट गायब हो जाता है। cron टास्क का आउटपुट यूज़र को ईमेल करता है। हमारी इमेज में मेल सर्वर नहीं है, इसलिए journal में (CRON) info (No MTA installed, discarding output) आया और आउटपुट खो गया। इसे ख़ुद रीडायरेक्ट करें, जैसे पहले उदाहरण में >> /var/log/backup.log 2>&1 से किया गया।

जाल 2: प्रतिशत का चिह्न। crontab में % कमांड ख़त्म कर देता है और बाकी हिस्से को स्टैंडर्ड इनपुट बना देता है। हमने date +%F > /tmp/today शेड्यूल किया। journal दिखाता है कि cron ने असल में क्या चलाया: CMD (date +)। कोई फ़ाइल नहीं बनी और कोई एरर हम तक नहीं पहुँचा। \% लिखें, या कमांड को स्क्रिप्ट में रखकर स्क्रिप्ट शेड्यूल करें।

जाल 3: अलग माहौल। cron टास्क bash की जगह /bin/sh से, आपके होम फ़ोल्डर में और सीमित माहौल के साथ चलाता है। Ubuntu 24.04 पर PATH अपनी साख से बेहतर निकला: /usr/local/bin और /snap/bin समेत पूरा सिस्टम पाथ, root और सामान्य यूज़र दोनों के लिए। जो अब भी नहीं है वह होम फ़ोल्डर के नीचे की हर चीज़ है: ~/.local/bin, nvm का node, pipx और cargo। टास्क में पूरे पाथ दें या लाइन . $HOME/.profile; से शुरू करें।

जो टास्क यूज़र के नहीं बल्कि सिस्टम के हों, वे /etc/cron.d/ में फ़ाइल के रूप में रखे जाते हैं, एक अतिरिक्त फ़ील्ड यानी यूज़र के साथ:

30 3 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Ubuntu /etc/cron.hourly, cron.daily, cron.weekly और cron.monthly में मौजूद हर चीज़ भी चलाता है: हर घंटे के 17वें मिनट पर, 06:25 पर, रविवार को 06:47 पर और महीने की 1 तारीख़ को 06:52 पर। वहाँ एक एक्ज़ीक्यूटेबल स्क्रिप्ट रखें और वह बाकियों के साथ चलेगी।

2. systemd टाइमर

टाइमर दो यूनिट होते हैं: काम करने वाली सर्विस और यह बताने वाला टाइमर कि कब। पहले स्क्रिप्ट बनाएँ, फिर यूनिट।

sudo nano /usr/local/bin/backup.sh
sudo chmod +x /usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the backup every night at 03:30

[Timer]
OnCalendar=*-*-* 03:30
Persistent=true
AccuracySec=1m

[Install]
WantedBy=timers.target

सर्विस नहीं, टाइमर चालू करें:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer

list-timers अगला रन, उसमें बचा समय और आख़िरी रन दिखाता है। लॉग को सेटअप की ज़रूरत नहीं: journalctl -u backup.service में हर शुरुआत, हर अंत और आउटपुट की हर लाइन समय के साथ होती है। टास्क अभी चलाने के लिए sudo systemctl start backup.service; शेड्यूल पर भरोसा करने से पहले स्क्रिप्ट भी इसी तरह परखें।

कैलेंडर सिंटैक्स। OnCalendar ऐसे पढ़ा जाता है: हफ़्ते-का-दिन साल-महीना-दिन घंटा:मिनट:सेकंड, और * किसी भी मान के लिए। इस्तेमाल से पहले एक्सप्रेशन परखें:

systemd-analyze calendar "Mon..Fri *-*-* 03:00" --iterations 2

यह नॉर्मलाइज़्ड रूप और अगली तारीख़ें छापता है। कुछ एक्सप्रेशन जो हमने जाँचे:

OnCalendarमतलब
*-*-* 03:30हर दिन 03:30 पर
Mon..Fri *-*-* 09:00कामकाजी दिनों में 09:00 पर
*:0/15हर 15 मिनट में
weeklyसोमवार को 00:00 पर
*-*-01 04:00हर महीने की 1 तारीख़ को 04:00 पर
*-*-* 03:00 Europe/Kyivकीव के समय 03:00; हमारे टेस्ट में 01:00 UTC पर चला

तीन सेटिंग जो जानने लायक हैं। Persistent=true आख़िरी रन डिस्क पर सहेजता है और वह रन पूरा करता है जो सर्वर बंद रहने या टाइमर रुके रहने के दौरान छूट गया। हमने अपना हर दो मिनट वाला टाइमर रोका, एक शेड्यूल रन निकल जाने दिया और फिर शुरू किया: छूटा रन उसी सेकंड में चल पड़ा। Persistent के बिना वह बस अगली बारी का इंतज़ार करता है।

असली सरप्राइज़ AccuracySec है। डिफ़ॉल्ट रूप से systemd सिस्टम को कम जगाने के लिए टाइमर को एक मिनट की विंडो में इकट्ठा करता है, इसलिए हमारा पहला रन 07:42:00 नहीं बल्कि 07:42:18 पर आया। AccuracySec=1s के साथ अगले रन ठीक सेकंड पर 07:46:00 और 07:48:00 पर हुए। जब मिनट मायने रखे तो इसे सेट करें; रात के बैकअप के लिए डिफ़ॉल्ट रहने दें।

RandomizedDelaySec=10m जानबूझकर उल्टा करता है: शुरुआत को एक विंडो में फैला देता है ताकि दस सर्वर एक ही सेकंड में एक ही बैकअप स्टोरेज पर न टूट पड़ें।

एक बार के टास्क के लिए किसी फ़ाइल की ज़रूरत नहीं:

sudo systemd-run --on-active=30m --unit=cleanup-once /usr/local/bin/cleanup.sh

यह एक अस्थायी टाइमर बनाता है जो एक बार चलता है और गायब हो जाता है; तब तक systemctl list-timers उसे दिखाता है।

3. कौन सा इस्तेमाल करें

cronsystemd टाइमर
सेटअप1 लाइन2 फ़ाइलें
लॉगसिर्फ़ अगर आउटपुट रीडायरेक्ट करेंjournalctl -u name.service
सर्वर बंद रहने के दौरान छूटा रनखो जाता हैPersistent=true से बूट पर चलता है
अगली बारी पर टास्क अब भी चल रहा हैदूसरी कॉपी शुरू हो जाती हैपहली ख़त्म होने तक छोड़ दिया जाता है
सटीक समयमिनट तकAccuracySec=1s से सेकंड तक
स्टेटसकोई नहींlist-timers और systemctl status

ऐसी तेज़ लाइन के लिए cron इस्तेमाल करें जिसे आप साल भर बाद भी पहचान लें। हर उस चीज़ के लिए टाइमर इस्तेमाल करें जिसकी विफलता आपको देखनी हो, जो ओवरलैप न होनी चाहिए या जिसे छूटे रीस्टार्ट के बाद भी चलना ज़रूरी हो: बैकअप, सर्टिफ़िकेट नवीनीकरण, डेटाबेस की सफ़ाई। अगर cron टास्क ओवरलैप हो सकता है तो उसे लपेट दें: flock -n /tmp/backup.lock /usr/local/bin/backup.sh, और दूसरी कॉपी तुरंत बाहर निकल जाएगी।

दोनों शेड्यूलर टास्क चलाते हैं और रुक जाते हैं। जिस प्रोग्राम को चौबीसों घंटे चलना और क्रैश के बाद वापस आना हो, उसे शेड्यूल नहीं, सर्विस चाहिए; देखें systemd सर्विस कैसे बनाएँ और Windows के लिए Windows Server पर स्क्रिप्ट 24/7 कैसे चलाएँ। एक अच्छा पहला टाइमर हमारी restic बैकअप गाइड वाला है; स्वचालित सुरक्षा अपडेट वह टाइमर हैं जो Ubuntu पहले से देता है, apt-daily-upgrade.timer, नए सर्वर पर चलने वाले 17 में से एक।

सामान्य प्रश्न

मेरा टास्क टर्मिनल में चलता है पर cron में नहीं, क्यों?

तीन आम कारण। cron टास्क को bash नहीं, sh से चलाता है, इसलिए सिर्फ़ bash वाला सिंटैक्स फ़ेल हो जाता है। होम फ़ोल्डर में इंस्टॉल टूल जैसे nvm, pipx या cargo, cron के PATH में नहीं होते, इसलिए पूरे पाथ इस्तेमाल करें। और कमांड लाइन में हर % कमांड ख़त्म कर देता है: हमारे सर्वर पर date +%F बदलकर date + हो गया। इसे \% लिखें या कमांड को स्क्रिप्ट में ले जाएँ।

cron का आउटपुट कहाँ जाता है?

डिफ़ॉल्ट रूप से ईमेल पर। हमारी इमेज में मेल सर्वर नहीं है, इसलिए cron लॉग करता है 'No MTA installed, discarding output' और आउटपुट खो जाता है। टास्क में >> /var/log/myjob.log 2>&1 जोड़ें, या systemd टाइमर पर जाएँ जिसका आउटपुट अपने आप journal में पहुँचता है।

systemd टाइमर का cron पर क्या फ़ायदा है?

journalctl में लॉग, पहले से चल रहे टास्क की दूसरी कॉपी शुरू नहीं होती, सर्वर बंद रहने के दौरान छूटे रन Persistent=true से पूरे होते हैं, और स्टेटस लाइन अगला और आख़िरी रन दिखाती है। cron संक्षिप्तता में जीतता है: दो फ़ाइलों की जगह एक लाइन।

मेरा टाइमर 18 सेकंड देर से चला। क्यों?

डिफ़ॉल्ट रूप से systemd सिस्टम को कम जगाने के लिए टाइमर को एक मिनट की विंडो में इकट्ठा करता है; यही AccuracySec सेटिंग है। हमारा हर दो मिनट वाला टाइमर 07:42:00 की जगह 07:42:18 पर चला। AccuracySec=1s के साथ यह ठीक 07:46:00 पर चला। जब सटीक मिनट मायने रखे तो इसे सेट करें।

cron और टाइमर कौन सा टाइम ज़ोन इस्तेमाल करते हैं?

सर्वर का, जो हमारी इमेज पर UTC है। इसे timedatectl से एक बार सेट करें, होस्टनेम और टाइम ज़ोन वाली हमारी गाइड देखें, और cron और टाइमर उसी का पालन करेंगे। टाइमर अपना ज़ोन भी रख सकता है: OnCalendar=*-*-* 03:00 Europe/Kyiv हमारे टेस्ट में 01:00 UTC पर चला।

टिप्पणियाँ

अभी तक कोई टिप्पणी नहीं। पहले बनें।

एक टिप्पणी छोड़ें

टिप्पणियाँ दिखने से पहले मॉडरेट की जाती हैं।