আধুনিক যেকোনো distro-তে নিজের মালিকানাধীন সব কাজের জন্য systemd timer নিন, আর cron রাখুন এক লাইনের user job ও নিজে সেট আপ করেননি এমন server-এর জন্য। Timer প্রতিটি run journal-এ লগ করে, মেশিন বন্ধ থাকার সময় মিস হওয়া schedule ধরে ফেরত চালাতে পারে, আর সিস্টেমের বাকি সবকিছুর মতো একই unit file-এর ওপর দাঁড়ায়। Cron জেতে সংক্ষিপ্ততায় — crontab -e-র এক লাইন দুটি unit file-কে হারায় — আর minimal container ও বাজে Unix বক্সে এটিই একমাত্র scheduler, যে থাকবেই নিশ্চিত। ধরাই সে: cron নীরবে ব্যর্থ হয়। ভোর ৩টায় job ভুল করলে cron এমন একটি লোকাল mailbox-এ মেইল পাঠায় যেটি কেউ পড়ে না, অথচ timer দেয় journalctl -u mytimer.service — পুরো আউটপুট সহ। নিচে: আসল পার্থক্যগুলো, প্রত্যেকটি টেস্ট করার পদ্ধতি, timer ট্রিগার না হওয়ার কারণ, আর একটি decision table।
cron আর systemd timer-এর মধ্যে পার্থক্য কী?
Cron একটি daemon, যা লাইনের একটি টেবিল পড়ে — পাঁচটি সময়-ফিল্ড আর একটি কমান্ড — আর ঘড়ির সময় মিললেই প্রতিটি কমান্ড চালায়। পুরো মডেল এটুকুই। এখানে job কোনো অবজেক্টই নয়: unit নেই, status নেই, dependency নেই, নিজস্ব কোনো লগ এন্ট্রিও নেই।
systemd timer হলো একটি unit file (foo.timer), যা নিজের schedule মিললে আরেকটি unit file (foo.service) চালু করে। Job এখানে first-class অবজেক্ট — যেকোনো অন্য service-এর মতো start, status, logs আর failure tracking সহ। Scheduling দুই রকম: calendar-ভিত্তিক (cron-এর মতো) নয়তো monotonic (OnBootSec=15min — ঘড়ির সময় বদলালেও এটি বিভ্রান্ত হয় না)।
বাস্তবে এর প্রভাব:
- Logging: timer প্রতি unit-এর stdout/stderr journal-এ লগ করে; cron সর্বোচ্চ লোকাল user-কে মেইল পাঠায়।
- মিস হওয়া run:
Persistent=trueদেওয়া timer তার schedule মিস হলে boot-এ একবার চালু হয়; cron শুধু বাদ দিয়ে দেয়। - Dependency: timer
network-online.targetবা mount point-এর জন্য অপেক্ষা করতে পারে; cron-এ retry logic স্ক্রিপ্টে হাতে লিখতে হয়। - Syntax: cron এক লাইন; timer দুটি ফাইল। পাল্টানোর পুরো খরচ এটুকুই।
কোন schedule syntax সহজ — crontab না OnCalendar?
Cron-এর পাঁচটি ফিল্ড হলো প্রচলিত সংক্ষিপ্ত ফরম্যাট: */15 * * * * মানে প্রতি ১৫ মিনিটে, আর বেশিরভাগ admin ঘুম ঘুম চোখেও এগুলো পড়তে পারেন। Systemd-এর OnCalendar= বেশি লম্বা কিন্তু স্পষ্টভাবে বেশি expressive — আর systemd-analyze calendar কমিট করার আগেই পরের run-গুলো বলে দেয়; cron-এর এমন কোনো dry-run নেই।
# Cron: প্রতিদিন ০৩:৩০-এ
30 3 * * * /usr/local/bin/backup.sh
# systemd: একই schedule, সেভ করার আগেই যাচাইযোগ্য
systemd-analyze calendar "*-*-* 03:30:00"
# -> পরবর্তী চালু: Fri 2026-09-11 03:30:00 ... OnCalendar এমন সব কাজও করে যা cron আসলে পরিষ্কারভাবে প্রকাশই করতে পারে না: Mon..Fri *-*-* 09..17:00:00 (কর্মদিবস, অফিস-টাইম), অথবা *:0/15 সঙ্গে RandomizedDelaySec=10m — যাতে হাজারখানেক মেশিন একই মুহূর্তে server-এ চাপা না দেয়।
অপেক্ষা না করে systemd timer কীভাবে টেস্ট করবেন?
তিনটি কমান্ডই সব বলে দেয়। কী schedule হয়েছে আর কখন পরের বার ফায়ার হবে তার তালিকা দেখুন, timer যেভাবে চালাত ঠিক সেভাবেই job-টি হাতে চালান, তারপর লগ পড়ুন:
systemctl list-timers --all # সব timer, পরের + শেষ run
sudo systemctl start backup.service # job এখনই চালান, timer-এর সেই unit-ই
journalctl -u backup.service -f # আউটপুট লাইভ দেখুন বিভাজনটি খেয়াল করুন: systemctl start backup.timer schedule-টি সচল করে; আসল service-ই হলো job। list-timers-এ আপনার timer দেখা যাচ্ছে, systemctl status backup.service সবুজ, আর journal-এ আউটপুট দেখা যাচ্ছে — পুরো চেইন কাজ করছে।
cron job কীভাবে হাতে চালাবেন?
Cron job একটি পাতলা environment-এ চলে — এ কারণেই “আমার shell-এ চলে, cron-এ ব্যর্থ” ধরনের বাগ একটি আলাদা genre হয়ে গেছে। Cron-কে বিশ্বাসযোগ্যভাবে নকল করতে কমান্ডটি sh দিয়ে চালান, cron যে environment ব্যবহার করত ঠিক সেটি সহ:
crontab -l # লাইনটি নিশ্চিত করুন
env -i SHELL=/bin/sh PATH=/usr/bin:/bin sh -c '/usr/local/bin/backup.sh'
grep CRON /var/log/syslog | tail # cron আদৌ চালিয়েছিল কি? (Debian/Ubuntu)
journalctl -u cron -n 20 # একই কাজ, systemd distro-তে ওই env -i লাইনটিই সৎ ম্যানুয়াল টেস্ট: cron-এর ডিফল্ট PATH সহ একটি কাঁচা environment। নীরব cron-ব্যর্থতার বেশিরভাগই হয় খালি PATH বা কমান্ডে উদ্ধৃতিচিহ্নহীন %-এর কারণে (cron %-কে newline ধরে), আর দুটোই এই পদ্ধতিতে সঙ্গে সঙ্গে ধরা পড়ে।
আমার systemd timer কেন ট্রিগার হচ্ছে না?
প্রায় প্রতিটি কেস চারটি কারণেই ঢেকে যায় — যাচাইয়ের ক্রম এই:
- Service আর timer-এর নাম মিলছে না।
foo.timerচালু করেfoo.service— ভুল টাইপেরOnFailureবা নাম বদলানো unit মানে timer “চলছে” কিন্তু কোথাও পড়ছে না।systemctl cat foo.timerঠিক কী টার্গেট করছে সেটিই দেখায়। - Timer সম্পাদনা হয়েছে কিন্তু reload হয়নি। Unit file বদলানোর পর:
sudo systemctl daemon-reload && sudo systemctl restart foo.timer। এটি ছাড়া নতুন schedule চালুই হয় না। Persistent=true, কিন্তু প্রত্যাশিতOnCalendarআচরণ নেই — নয়তো আপনিlist-timers-এর বদলেsystemctl status foo.timerদেখছেন (idle থাকলেও এটি সবসময় active দেখায়)।- যে service চালু হয় সেটি সঙ্গে সঙ্গে ব্যর্থ হচ্ছে, তাই timer মরা মনে হয়।
journalctl -u foo.service --since -1hসেই crash দেখাবে যাlist-timersলুকিয়ে রাখে।
আর লগ দেখার পালা এলে journalctl cheat sheet-এ সেই ফিল্টারগুলো (-u, --since, -f) আছে যেগুলো কাজটা দ্রুত করে।
Cron বনাম systemd timer: decision table
| cron | systemd timer | |
|---|---|---|
| সেটআপ | crontab-এর এক লাইন | দুটি unit file |
| Logging | লোকাল মেইল, সাধারণত অপঠিত | journal, প্রতি unit-এ |
| মিস হওয়া run (মেশিন বন্ধ) | বাদ | Persistent=true দিলে boot-এ একবার চলে |
| Dependency / ক্রম | নেই — স্ক্রিপ্টে DIY | পূর্ণ unit dependency |
| Randomised delay | $RANDOM দিয়ে DIY | RandomizedDelaySec= |
| Schedule-এর টেস্ট/dry-run | নেই | systemd-analyze calendar |
| সব জায়গায় আছে | হ্যাঁ — container, BSD, embedded | systemd (PID 1) দরকার |
| root ছাড়া user job | crontab -e | systemd --user unit |
সহজ নিয়ম: নিজের systemd মেশিনে job পাঠাচ্ছেন → timer। দ্রুত ব্যক্তিগত রিমাইন্ডার বা নিজে বানাননি এমন বক্স → cron। Dependency, retry বা “আসলেই চলেছিল কি না” জানার প্রয়োজন — যার যা-ই থাকুক → সবসময় timer। একটি প্রচলিত প্যাটার্ন: রাতের rsync backup-এর মতো maintenance job চালানো timer, যেখানে Persistent=true গ্যারান্টি দেয় নির্ধারিত মিনিটে মেশিন ঘুমিয়ে থাকলেও backup হবেই — cron এটি দিতেই পারে না।
— mrsaynothing
— mrsaynothing
AI, Linux ও self-hosting নিয়ে ফিল্ড নোটস।
পোস্টটি নিয়ে dev.to-তে আলোচনা করুন dev.to ↗
পরের হাউ-টু ইমেইলে পান
প্রতি পোস্টে একটি ইমেইল। সমাধান করুন, এগিয়ে যান।
এটা কী?llama.cpp vs Ollama: 2026-এ কোনটি চালাবেন?
লেখাগুলো ভালো লাগছে? এমন জিনিস বানানোই আমার পেশা। আমাকে নিন