Cron job क्यों नहीं चल रहा है? मुख्य कारण और समाधान
आपका Cron job क्यों नहीं चल रहा है? इसके पांच मुख्य कारण हैं जिनमें सीमित PATH, अनएस्केप्ड प्रतिशत चिह्न, गलत crontab फाइल, खोया हुआ मेल आउटपुट और शेल निर्भरता शामिल हैं।
आपका cron job क्यों नहीं चलता
एक cron job जो "कभी नहीं चलता", वह लगभग हमेशा चल चुका होता है। यह एक ऐसे environment में चला जो आपका shell नहीं है, यह पहली ही सेकंड में fail हो गया, और इसका संदेश कहीं ऐसी जगह चला गया जिसे आप पढ़ नहीं रहे हैं। पाँच कारण लगभग हर रिपोर्ट की व्याख्या करते हैं: search path, percent sign, गलत crontab file, mail पर गया output, और एक script जिसे login session की अपेक्षा है।
cron एक daemon (एक background service) है जो crontab files को पढ़ता है और schedule के अनुसार commands शुरू करता है। यह आपकी .bashrc को नहीं पढ़ता, यह terminal नहीं खोलता, यह login shell शुरू नहीं करता, और यह आपको यह नहीं बताता कि command कब fail होती है। नीचे दिए गए सभी कारण उन चार तथ्यों से उत्पन्न होते हैं।
इन पर क्रमवार काम करें, और उन सभी के नीचे दिए गए प्रश्न से शुरुआत करें: क्या cron वास्तव में चला? "cron ने job कभी शुरू नहीं किया" और "job शुरू हुआ और मर गया" अलग-अलग समस्याएँ हैं जिनमें कुछ भी समान नहीं है, इसलिए पहले उस प्रश्न का उत्तर दें।
क्या cron चला था?
daemon का नाम अलग-अलग distribution परिवारों पर अलग-अलग होता है। दोनों की जाँच करें, फिर log पढ़ें।
systemctl status cron
systemctl status crond
journalctl -u cron --since "2 hours ago"
journalctl -u crond --since "2 hours ago"Debian और Ubuntu में unit का नाम cron होता है। Fedora, Rocky और Alma में इसे crond कहा जाता है। किसी भी मशीन पर इनमें से केवल एक ही नाम मौजूद होता है, इसलिए यदि एक command 'unknown unit' की रिपोर्ट दे, तो यह सामान्य है और कोई त्रुटि नहीं है।
अपने सिस्टम द्वारा लिखी गई entries को पढ़ें। किसी गाइड से कॉपी की गई लाइन को न खोजें, क्योंकि cron के अलग-अलग implementations और logging setups के बीच शब्दों का चयन भिन्न होता है। आप केवल दो चीजों की जाँच कर रहे हैं: क्या आपके schedule के मिनट पर कोई entry है, और क्या उस entry में आपकी command का नाम है। यदि entry में आपकी command का नाम है, तो इसका मतलब है कि cron ने अपना काम किया और समस्या command के भीतर है। यदि कोई entry नहीं है, तो इसका मतलब है कि cron के पास आपका schedule कभी पहुँचा ही नहीं, जो नीचे दिए गए कारण 3 का परिणाम है।
कुछ images cron के संदेशों को journal के बजाय rsyslog के माध्यम से एक file में भेजती हैं। /var/log में cron या syslog के नाम वाली file खोजें, फिर उसके अंत को पढ़ें।
ls -l /var/log
sudo tail -n 50 /var/log/syslogयदि unit और log दोनों मौजूद नहीं हैं, तो हो सकता है कि cron install ही न हो। Minimal cloud images और containers में अक्सर इसे शामिल नहीं किया जाता है।
dpkg -l cron
rpm -q cronie
sudo apt install cron
sudo dnf install cronie
sudo systemctl enable --now cronकारण 1: cron के पास आपका PATH नहीं है
आपका interactive shell PATH को /etc/profile, ~/.profile, ~/.bashrc और उन फाइलों द्वारा सोर्स की गई हर चीज से बनाता है। cron job के लिए इनमें से कुछ भी रन नहीं होता है। cron कमांड को अपने छोटे environment के साथ शुरू करता है, इसलिए जो प्रोग्राम standard system directories के बाहर स्थित होते हैं, वे नहीं मिल पाते हैं। /usr/local/bin, /opt, language version manager, Python virtual environment या Go workspace के अंतर्गत मौजूद कोई भी चीज इसके दायरे में आती है। job अपनी पहली लाइन पर ही विफल हो जाता है, और shell एक "not found" प्रकार की error लिखता है, जिसके सटीक शब्द इस पर निर्भर करते हैं कि कौन सा shell उसे चला रहा था।
अपनी job द्वारा उपयोग की जाने वाली प्रत्येक कमांड का वास्तविक path पता करें।
command -v docker
command -v node
readlink -f "$(command -v node)"इसके बाद या तो उन absolute paths को job में लिखें, या crontab के शीर्ष पर एक बार PATH सेट करें।
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 3 * * * /usr/local/bin/mytool runअपनी मशीन से echo "$PATH" के साथ वह सूची लें और ऐसी किसी भी चीज को हटा दें जो केवल interactive session के अंदर मौजूद है। यहाँ एक नियम मायने रखता है: cron इन assignment lines में variables को expand नहीं करता है। PATH=$PATH:/usr/local/bin literal text $PATH:/usr/local/bin को स्टोर करता है, इसलिए job अंततः एक ऐसे search path के साथ समाप्त होती है जिसमें कोई भी उपयोगी directory नहीं होती है। पूरी सूची लिखें।
version manager को केवल path से अधिक की आवश्यकता होती है। nvm, pyenv, rbenv और asdf आपके .bashrc से एक shell function या shims directory इंस्टॉल करते हैं, और cron job उस फाइल को कभी नहीं पढ़ता है। versioned binary को absolute path द्वारा कॉल करें, या अपनी स्क्रिप्ट की पहली लाइन के रूप में manager की init script को सोर्स करें।
कारण 2: प्रतिशत का चिह्न आपके कमांड को समाप्त कर देता है
crontab के कमांड फील्ड में, % एक सामान्य वर्ण नहीं है। पहला unescaped % कमांड को समाप्त कर देता है। इसके बाद जो कुछ भी होता है, उसे standard input के रूप में कमांड को भेजा जाता है, और प्रत्येक अतिरिक्त % एक नई लाइन (newline) बन जाता है। यह किसी प्रोग्राम को संक्षिप्त इनपुट देने के लिए एक वास्तविक cron फीचर है, और यही कारण है कि date-stamped filename एक क्लासिक टूटी हुई crontab एंट्री है।
0 3 * * * /usr/bin/tar -czf /srv/backups/site-$(date +%F).tar.gz /srv/site लिखें और tar कभी भी formatted date नहीं देख पाएगा। cron लाइन को पहले % पर काट देता है, इसलिए shell को एक अधूरा command substitution प्राप्त होता है और आपकी लाइन का बाकी हिस्सा standard input के रूप में पहुँच जाता है। प्रत्येक प्रतिशत चिह्न को backslash के साथ escape करें।
0 3 * * * /usr/bin/tar -czf /srv/backups/site-$(date +\%F).tar.gz /srv/siteदो परतें (layers) उस एक लाइन को क्रम में पढ़ती हैं। \% एक cron नियम है, जिसे cron किसी भी चीज़ को शुरू करने से पहले लागू करता है। $(date +\%F) एक command substitution है, जिसे बाद में उस shell द्वारा लागू किया जाता है जिसे cron शुरू करता है। यह जानना कि कौन सा वर्ण किस परत का है, यही पूरी तरकीब है।
सुरक्षित आदत यह है कि logic को पूरी तरह से crontab से बाहर रखा जाए। इसे एक script में रखें, जहाँ प्रतिशत चिह्न का कोई विशेष अर्थ नहीं होता है।
#!/bin/bash
set -euo pipefail
stamp="$(date +%F)"
tar -czf "/srv/backups/site-${stamp}.tar.gz" /srv/sitecrontab लाइन में तब केवल एक path और एक redirect होता है और कुछ नहीं। एक crontab जिसे आप एक नज़र में पढ़ सकते हैं, वह एक ऐसी crontab है जिसे आप debug कर सकते हैं।
कारण 3: आपने किस crontab को एडिट किया?
कोई एक एकल crontab नहीं होता है। कई फाइलें होती हैं, जिनके मालिक अलग-अलग होते हैं और जिनमें fields की संख्या भी भिन्न होती है। गलत फाइल में लिखा गया job दिखाई नहीं देता है।
crontab -eउस user का crontab एडिट करता है जो command चलाता है।sudo crontab -eroot का crontab एडिट करता है। एक ही सर्वर को debug कर रहे दो लोग अक्सर दो अलग-अलग फाइलें देख रहे होते हैं।sudo crontab -l -u deployकिसी अन्य user का crontab लिस्ट करता है। इसी तरह आप पुष्टि करते हैं कि उस account के लिए वास्तव में क्या install है जिसे job चलानी चाहिए।/etc/crontabऔर/etc/cron.dकी हर फाइल में schedule और command के बीच एक अतिरिक्त field होता है: वह user जिसके रूप में job चलानी है। यदि आप पांच-field वाली user crontab लाइन को/etc/cron.dमें पेस्ट करेंगे, तो आपकी command के पहले शब्द को username मान लिया जाएगा।/etc/cron.dकी फाइलों के नाम में केवल अक्षर, अंक, underscores और hyphens होने चाहिए।backup.shयाsite.confजैसी फाइल को उसके नाम के कारण ही छोड़ दिया जाता है। इसेbackupपर rename करें और अपना log फिर से देखें।/etc/cron.dकी फाइलें root के स्वामित्व में होनी चाहिए और group या अन्य users द्वारा writable नहीं होनी चाहिए।ls -l /etc/cron.dआपको ये दोनों तथ्य एक साथ दिखाता है।/etc/cron.dailyऔर उसकी संबंधित directories में डाली गई scripts पर भी वही naming नियम लागू होते हैं और उनमें execute bit का होना अनिवार्य है। execute bit न होने पर script चुपचाप छोड़ दी जाती है।/etc/cron.allowऔर/etc/cron.denyयह तय करते हैं कि crontab install करने की अनुमति किसे है। यदि आपके सर्वर पर इनमें से कोई भी फाइल मौजूद है, तो यह मानने से पहले कि आपके user को अनुमति है, उसे पढ़ लें।
crontab फाइल को हाथ से एडिट करने के बजाय crontab command का उपयोग करके user crontab install करें, क्योंकि crontab install करने से पहले फाइल को parse करता है। save करने के बाद, command द्वारा दिए गए output को पढ़ें। यदि यह फाइल को अस्वीकार कर देता है, तो पिछला संस्करण ही सक्रिय रहता है और आपका बदलाव लागू नहीं होता, जो बिल्कुल ऐसा लगता है जैसे cron आपको अनदेखा कर रहा हो।
मालिक (owner) अनुमतियों (permissions) को भी निर्धारित करता है। root के crontab में मौजूद job ऐसी फाइलें बनाती है जिनका मालिक root होता है, जिन्हें पढ़ने वाला application शायद write न कर पाए। एक सामान्य user के crontab में मौजूद job root-only directory को नहीं पढ़ सकती। मालिक को कार्य के अनुरूप रखें: application का रखरखाव उसी application के account द्वारा किया जाना चाहिए, यही कारण है कि WordPress wp-cron को system cron job से बदलना उचित है। आपके job द्वारा बनाई गई फाइलों का mode उसके द्वारा inherit किए गए umask से आता है, और यह वह मान है जो आपके shell से अलग हो सकता है, इसलिए यदि job का output अपठनीय (unreadable) हो, तो umask फाइल अनुमतियाँ कैसे सेट करता है पढ़ना उपयोगी है।
कारण 4: आउटपुट ऐसे मेल पर गया जिसे कोई नहीं पढ़ता
cron किसी जॉब द्वारा standard output और standard error पर लिखी गई हर चीज़ को इकट्ठा करता है। यदि जॉब ने कुछ भी लिखा है, तो cron उस टेक्स्ट को स्थानीय मेल सिस्टम को सौंप देता है, जो crontab के मालिक या MAILTO द्वारा निर्दिष्ट किसी भी पते पर भेजा जाता है। एक सीमित VPS पर आमतौर पर कोई MTA (mail transfer agent) इंस्टॉल नहीं होता है, इसलिए कुछ भी डिलीवर नहीं होता है। आपकी त्रुटि एक पल के लिए मौजूद थी और फिर कहीं नहीं गई। यही कारण है कि एक खराब जॉब शांत दिखाई देती है।
आउटपुट को उस फ़ाइल पर भेजें जिसे आप नियंत्रित करते हैं।
0 3 * * * /usr/local/sbin/backup-site.sh >> /var/log/backup-site.log 2>&1>> standard output को फ़ाइल में जोड़ता है (append)। 2>&1 standard error को उस स्थान पर निर्देशित करता है जहाँ standard output अभी पॉइंट कर रहा है, इसलिए इसे रीडायरेक्ट के बाद आना चाहिए। यदि इसे दूसरी तरह से लिखा जाए, जैसे 2>&1 >> file, तो standard error अपने मूल गंतव्य पर ही बना रहता है, और जिस त्रुटि को आप ढूंढ रहे हैं, वह कभी फ़ाइल तक नहीं पहुँचती है।
journal एक और अच्छा विकल्प है। logger आपके द्वारा चुने गए टैग के तहत syslog में लिखता है।
0 3 * * * /usr/local/sbin/backup-site.sh 2>&1 | logger -t backup-siteइसे journalctl -t backup-site के साथ वापस पढ़ें। यह जॉब के अपने आउटपुट को cron प्रविष्टियों के पास रखता है, जिससे टाइमलाइन का पालन करना आसान हो जाता है। यदि आपको इस बात का रिकॉर्ड भी चाहिए कि सर्वर पर किस व्यक्ति ने कौन सा कमांड चलाया, तो वह एक अलग सिस्टम है, और auditing user commands on your server इसे कवर करता है।
crontab के शीर्ष पर MAILTO="" का उपयोग करने से उसके नीचे की जॉब्स के लिए मेल बंद हो जाता है। MAILTO को एक वास्तविक पते पर सेट करना केवल तभी मदद करता है जब कोई कार्यशील MTA मौजूद हो, इसलिए उस पर निर्भर होने से पहले यह सुनिश्चित करें कि मेल बॉक्स से बाहर जा रहा है।
डीबगिंग के दौरान एक नियम याद रखें: कभी भी > /dev/null 2>&1 न जोड़ें। यह हर crontab में सबसे लोकप्रिय लाइन है, और यह आपके पास मौजूद एकमात्र सबूत को नष्ट कर देती है। यदि आप चाहें तो जॉब के काम करने के बाद इसे वापस लगा सकते हैं।
कारण 5: स्क्रिप्ट ऐसे वातावरण की अपेक्षा करती है जो cron उसे नहीं देता है
एक बार जब कमांड मिल जाती है और उसका आउटपुट कैप्चर हो जाता है, तो बाकी वह सब कुछ बचता है जो आपका सेशन आपको मुफ्त में देता है।
- शेल bash नहीं हो सकता है।
ls -l /bin/shके साथ जाँचें। Debian और Ubuntu पर यह dash की ओर इशारा करता है, इसलिए डबल ब्रैकेट टेस्ट, ऐरे औरsourceसिंटैक्स एरर के साथ विफल हो जाते हैं। स्क्रिप्ट को एक#!/bin/bashलाइन दें और स्क्रिप्ट को कॉल करें, या crontab के शीर्ष परSHELLसेट करें। - वर्किंग डायरेक्टरी वह नहीं है जिसमें आप खड़े थे। हर जगह एब्सोल्यूट पाथ का उपयोग करें, या स्क्रिप्ट की पहली लाइन पर डायरेक्टरी के लिए
cdका उपयोग करें। एक रिलेटिव पाथ सबसे सामान्य कारण है कि कोई जॉब "मेरे द्वारा मैन्युअल रूप से चलाने पर काम करती है"। - लोकेल आपके सेशन का नहीं है। जो कुछ भी तारीख या संख्या को फॉर्मेट करता है, या टेक्स्ट को सॉर्ट करता है, वह अलग
LANGके तहत अलग आउटपुट दे सकता है। यदि बाद का कोई चरण उस आउटपुट को पार्स करता है, तो उम्मीद करने के बजाय स्क्रिप्ट में लोकेल सेट करें। - कोई TTY (टर्मिनल) नहीं है। जो कमांड पुष्टि मांगती है, एडिटर खोलती है या प्रोग्रेस बार दिखाती है, वह हैंग हो सकती है या बाहर निकल सकती है। टूल द्वारा प्रदान किया गया कोई भी नॉन-इंटरैक्टिव फ्लैग जोड़ें।
- कोई SSH एजेंट नहीं है।
SSH_AUTH_SOCKcron के वातावरण में नहीं है, इसलिए एकsshयाrsyncकमांड जो आपके एजेंट के लोड होने के कारण काम करती थी, अब ऑथेंटिकेट होने में विफल हो जाती है। जॉब को उसकी अपनी की (key) दें, जिसका स्वामित्व जॉब के यूजर के पास हो। - कोई यूजर सेशन बस नहीं है, इसलिए cron जॉब से
systemctl --userतब तक विफल रहता है जब तकXDG_RUNTIME_DIRसेट न हो। एक सिस्टम यूनिट बेहतर समाधान है।
Fedora, Rocky और Alma पर एक और संदिग्ध कारण है। SELinux cron जॉब्स को सीमित करता है, इसलिए किसी अनपेक्षित लेबल वाले पाथ को छूने वाली जॉब को तब भी अस्वीकार कर दिया जाता है जब फाइल अनुमतियाँ सही दिखती हैं। sudo ausearch -m avc -ts recent के साथ अस्वीकृतियों (denials) की जाँच करें, और किसी भी चीज़ को बंद करने से पहले SELinux basics for a server पढ़ें।
एक मिनट की जांच जो cron के environment को दर्शाती है
cron के environment में क्या है, यह अनुमान लगाना बंद करें और इसे स्वयं देखें। एक script लिखें जो सब कुछ dump कर दे, उसे हर मिनट के लिए schedule करें, प्रतीक्षा करें, और फिर file को पढ़ें।
cat > /home/deploy/cron-probe.sh <<'EOF'
#!/bin/bash
echo "=== probe ==="
date -Is
pwd
id
echo "SHELL=$SHELL"
echo "LANG=$LANG"
command -v node || echo "node is not on this PATH"
env | sort
EOF
chmod +x /home/deploy/cron-probe.shउस user के crontab में एक line जोड़ें जिसके अंतर्गत वास्तविक job चलती है, और दोनों तरफ absolute paths का उपयोग करें।
* * * * * /home/deploy/cron-probe.sh >> /home/deploy/cron-probe.log 2>&1एक मिनट प्रतीक्षा करें, फिर /home/deploy/cron-probe.log को पढ़ें और इसकी तुलना अपने shell में चलाए गए उन्हीं commands से करें। PATH line, working directory और locale अक्सर विफलता का कारण स्वयं स्पष्ट कर देते हैं। setup के दो विवरणों पर ध्यान दें: percent signs script के अंदर रहते हैं, जहाँ cron का नियम लागू नहीं होता है, और log path ऐसा है जिसमें job का user लिख सकता है।
जैसे ही आपको उत्तर मिल जाए, उस crontab line को हटा दें। जो job हर मिनट चलती है और file में append करती है, वह एक छोटी disk को भर देगी, और वह भी चुपचाप।
क्या आप इसी शेड्यूल की बात कर रहे थे?
एक user crontab लाइन पांच fields से शुरू होती है: minute, hour, day of month, month, day of week। इनमें से दो fields इस तरह से काम करते हैं जो लोगों को हैरान कर देते हैं।
जब day of month और day of week दोनों प्रतिबंधित (restricted) होते हैं, यानी उनमें से कोई भी * नहीं होता, तो cron उस job को तब चलाता है जब दोनों में से कोई भी field मैच हो जाए। 0 0 13 * 5 का मतलब "Friday the 13th" नहीं है। यह हर महीने की 13 तारीख को आधी रात को चलता है, और हर शुक्रवार को आधी रात को भी चलता है। किसी एक विशिष्ट दिन को चुनने के लिए, दोनों में से एक field को * छोड़ दें और script के अंदर दूसरे field का परीक्षण करें।
cron सिस्टम timezone का उपयोग करता है। कई VPS images UTC (coordinated universal time) पर सेट होकर आती हैं, इसलिए 03:00 के लिए शेड्यूल की गई job 03:00 UTC पर चलती है, जो आपके स्थानीय समय के अनुसार दोपहर का समय हो सकता है। timedatectl यह प्रिंट करता है कि आपका सर्वर वास्तव में किस समय का उपयोग कर रहा है। अपने लैपटॉप के समय के समान होने का अनुमान लगाने के बजाय, अपने सर्वर का समय स्वयं देखें।
शेड्यूल से जुड़ी दो और सावधानियां जानना जरूरी है। @reboot तब चलता है जब cron स्वयं start होता है, जो उस समय के समान नहीं है जब नेटवर्क तैयार होता है। इसलिए, DNS या remote host की आवश्यकता वाली job boot के समय विफल हो सकती है और बाद में हर manual run पर सफल हो सकती है। और कोई भी चीज एक धीमी job को दोबारा शुरू होने से नहीं रोकती, जबकि उसकी पिछली copy अभी भी चल रही हो। इसे एक lock में लपेटें।
*/5 * * * * /usr/bin/flock -n /tmp/backup-site.lock /usr/local/sbin/backup-site.sh >> /var/log/backup-site.log 2>&1flock -n तुरंत रुक जाता है जब lock पहले से ही held होता है, इसलिए overlapping run पहली job के ऊपर ढेर होने के बजाय रुक जाता है।
जब systemd timer एक बेहतर विकल्प हो
cron एक काम के लिए अच्छा है: किसी कमांड को एक निश्चित समय पर चलाना। अन्य सभी मामलों में यह कमजोर है। एक timer आपको बिना किसी redirect के journal प्रदान करता है, एक exit status जिसे आप बाद में query कर सकते हैं, network-online.target के विरुद्ध ordering, और एक randomized delay ताकि सौ सर्वर एक ही सेकंड में start न हों। जब आपके job को इनमें से किसी की भी आवश्यकता हो, तो VPS पर systemd service और timer का उपयोग करना crontab line को manage करने से कम मेहनत का काम है। service का हिस्सा लिखने पर आपसे एक ऐसा सवाल पूछा जाता है जो cron कभी नहीं पूछता, कि unit को कैसे पता चलेगा कि काम वास्तव में शुरू हो गया है, इसलिए पहले simple, forking और notify units के लिए Type= का अर्थ पढ़ें, क्योंकि जो script default type के तहत खुद को daemonize करती है, वह unit को active तो दिखाती है लेकिन पीछे कोई प्रक्रिया नहीं होती। Retry behaviour भी यहीं आता है, क्योंकि systemd restart policies तय करती हैं कि विफलता के बाद क्या होगा, और cron के पास इस सवाल का कोई जवाब नहीं है।
छोटे कार्यों के लिए cron का उपयोग जारी रखें। dependencies या retry policy वाले किसी भी कार्य को timer पर ले जाएं। दोनों एक ही सर्वर पर चल सकते हैं, इसलिए यह ऐसा migration नहीं है जिसे आपको एक ही बार में पूरा करना हो।
FAQ
मेरा cron job मैन्युअल रूप से चलाने पर काम करता है लेकिन cron से विफल क्यों हो जाता है?
क्योंकि आपका shell और cron का environment अलग-अलग होते हैं। आपका login shell /etc/profile और ~/.bashrc को पढ़ता है, जो PATH, locale और आपके agent variables को सेट करते हैं। cron कमांड को इनमें से किसी के बिना, एक अलग working directory से और कभी-कभी एक अलग shell के साथ शुरू करता है। हर कमांड के लिए absolute paths का उपयोग करें, crontab के शीर्ष पर या script के अंदर जो आवश्यक है उसे सेट करें, और एक मिनट का probe job शेड्यूल करें जो env | sort, pwd और id को एक log file में लिखता हो ताकि आप अनुमान लगाने के बजाय cron का वास्तविक environment देख सकें।
मैं यह कैसे जाँचूँ कि क्या cron ने वास्तव में मेरा job चलाया है?
daemon के log को पढ़ें। Debian और Ubuntu पर journalctl -u cron का उपयोग करें, या Fedora, Rocky और Alma पर journalctl -u crond का उपयोग करें; कुछ images संदेशों को rsyslog के माध्यम से /var/log के अंतर्गत एक file में भेजते हैं। उस मिनट पर एक entry देखें जो आपके शेड्यूल में है और सुनिश्चित करें कि वह आपकी कमांड का नाम दिखाती है। यदि कोई entry नहीं है, तो इसका मतलब है कि cron के पास वह शेड्यूल कभी नहीं था, इसलिए पुष्टि करें कि आपने सही crontab को edit किया है। यदि entry है लेकिन कोई परिणाम नहीं है, तो इसका मतलब है कि कमांड शुरू हुई और बंद हो गई, इसलिए इसके output को redirect करके capture करें।
crontab के अंदर date +%Y काम क्यों नहीं करता है?
cron कमांड field में % को विशेष मानता है। पहला unescaped % कमांड को समाप्त कर देता है, उसके बाद की हर चीज़ उस कमांड को standard input के रूप में भेजी जाती है, और प्रत्येक अतिरिक्त % एक newline बन जाता है। इसलिए date-formatted filename उस प्रोग्राम तक कभी नहीं पहुँचता जिसके लिए आपने इसे लिखा था। प्रत्येक percent को \% के रूप में escape करें, या कमांड को एक script में ले जाएँ और cron से उस script को call करें, क्योंकि script के अंदर percent sign का कोई विशेष अर्थ नहीं होता है।
मेरे cron job का output कहाँ जाता है?
यह local mail system में जाता है, जो crontab के मालिक को या जो भी MAILTO में नाम दिया गया है, उसे संबोधित होता है। अधिकांश VPS images में कोई mail transfer agent install नहीं होता है, इसलिए संदेश को discard कर दिया जाता है और job silent दिखता है। output को >> /path/to/log 2>&1 के साथ एक file में redirect करें, इस क्रम को बनाए रखें ताकि standard error, standard output का अनुसरण करे, या इसे logger -t myjob के माध्यम से pipe करें और journalctl -t myjob के साथ वापस पढ़ें। जब तक आप debugging कर रहे हों, तब तक > /dev/null 2>&1 का उपयोग न करें।
क्या मुझे cron या systemd timer का उपयोग करना चाहिए?
एक निश्चित समय पर साधारण कमांड के लिए cron का उपयोग करें, विशेष रूप से तब जब आपको इसे ऐसी मशीन पर ले जाने की आवश्यकता हो सकती है जो systemd नहीं चलाती है। जब आप output को redirect किए बिना journal में चाहते हैं, या queryable exit status, network चालू होने के बाद ordering, randomized start delay, या विफलता के बाद retry policy चाहते हैं, तो timer का उपयोग करें। दोनों एक ही सर्वर पर चल सकते हैं, इसलिए आप jobs को एक-एक करके स्थानांतरित कर सकते हैं जैसे-जैसे उनकी आवश्यकता बढ़ती है।