کرونجاب، ساعت زنگدار سرور است: هر کاری که باید سر وقت و بدون اتکا به حافظهٔ آدمها تکرار شود (بکاپ شبانه، پاکسازی فایلهای موقت، گزارش هفتگی، هشدار خرابی) با یک خط زمانبندی به cron سپرده میشود و دیگر فراموش نمیشود. در راهنماهای قبلی بارها گفتیم «این کار را زمانبندی کنید»؛ این مقاله همان حلقهٔ گمشده است: نحو crontab با مثالهای واقعی، مشکل معروف WP-Cron در وردپرس و درمان استانداردش، و پنج قانونی که کرونِ شما را از «امیدوارم اجرا شده باشد» به ابزار قابلاعتماد تبدیل میکند.

نحو crontab؛ پنج ستون و تمام
هر خط crontab پنج ستون زمان دارد و بعد، فرمانی که باید اجرا شود: دقیقه، ساعت، روزِ ماه، ماه، و روزِ هفته. ستارهٔ هر ستون یعنی «هر مقداری». مرجع کامل نحو، صفحهٔ man رسمی crontab است؛ ولی در عمل، چند الگو نود درصد نیازها را میپوشاند:
30 3 * * * /usr/local/bin/backup.sh # هر شب ۰۳:۳۰
*/5 * * * * /usr/local/bin/health-check.sh # هر ۵ دقیقه
0 7 * * 6 /usr/local/bin/weekly-report.sh # شنبهها ۰۷:۰۰
0 2 1 * * /usr/local/bin/monthly-clean.sh # اولِ هر ماه ۰۲:۰۰
@reboot /usr/local/bin/warmup.sh # بعد از هر ریاستارت
| نیاز | الگو | نکته |
|---|---|---|
| پایش مکرر | */5 * * * * | فاصلهٔ کمتر از این را بیشتر هاستها محدود میکنند |
| کار شبانه | 30 3 * * * | ساعت کمترافیک سایت خودتان را از لاگ دربیاورید |
| کار هفتگی | 0 7 * * 6 | ستون آخر روز هفته است: ۰ یکشنبه تا ۶ شنبه |
| کار ماهانه | 0 2 1 * * | برای گزارش و آرشیو لاگ و تمدیدچکها |
| بعد از ریاستارت | @reboot | برای سرویسهایی که باید همیشه بالا باشند |
دو جای تنظیم دارد: روی هاست اشتراکی، از بخش Cron Jobs پنل (برای سیپنل، آموزش فعال کردن Cron Jobs در سی پنل را داریم) و روی سرور مجازی، با فرمان crontab -e برای همان کاربری که باید کار را اجرا کند. محتوای هر دو یکی است؛ پنل فقط همین پنج ستون را فرمدار کرده.
سه عادت ویرایش هم از همان روز اول نظم میسازد. همیشه از crontab -e استفاده کنید، چون موقع ذخیره، نحو را چک میکند و خطای تایپی را همانجا میگیرد. قبل از هر تغییر بزرگ، یک نسخهٔ پشتیبان از جدول فعلی بگیرید: crontab -l > crontab-backup.txt؛ یک خطِ اشتباه پاکشده، ساعتها بازسازی از حافظه میخواهد. و بالای هر خط، یک کامنت بنویسید که این کار چیست و چرا این ساعت؛ crontab ششماهبعد، بدون کامنت، برای خودتان هم رمزنگاریشده است.
مشکل WP-Cron؛ زمانبندیِ وردپرس به بازدید گره خورده است
وردپرس زمانبند داخلی خودش را دارد، ولی با یک تفاوت مهم که مستند رسمی وردپرس صریح میگوید: WP-Cron فقط هنگام بازدید صفحه اجرا میشود. نتیجه در دو سر طیف خودش را نشان میدهد. سایت کمبازدید: کارها سر وقت اجرا نمیشوند؛ پست زمانبندیشده ساعتها دیر منتشر میشود و بکاپ افزونهای که منتظر WP-Cron است، شبهای بیبازدید اصلاً اجرا نمیشود. سایت پربازدید: برعکس، همان بررسیِ «کاری عقب نیفتاده؟» روی درخواستها سربار میگذارد و در فروشگاههای شلوغ، جزو قلمهای بهینهسازی است که در ووکامرس در مقیاس بالا به آن رسیدیم.
درمان استاندارد، جدا کردن زمانبندی از بازدید است و دو قدم دارد. اول در wp-config اعلام کنید که شبهکرون خاموش شود:
define('DISABLE_WP_CRON', true);
بعد یک کرون واقعی بسازید که هر پنج دقیقه همان موتور را صدا بزند:
*/5 * * * * wget -q -O - https://example.ir/wp-cron.php?doing_wp_cron >/dev/null 2>&1
از این به بعد، انتشار زمانبندیشده، بکاپ افزونهای و همهٔ رویدادهای وردپرس، مستقل از اینکه کسی سایت را باز کند، سر وقت اجرا میشوند. این تغییر را هم مثل هر تغییر دیگری اول روی سایت تست انجام بدهید و بعد روی سایت اصلی.
پنج قانون کرونِ قابلاعتماد
- مسیرهای مطلق: کلاسیکترین خرابی کرون همین است: محیط اجرای cron تقریباً خالی است و PATH کاملش را ندارد؛ اسکریپتی که در ترمینال شما کار میکند، ساعت ۰۳:۳۰ با «command not found» بیصدا میمیرد. در اسکریپتهای کرون، فرمانها را با مسیر کامل بنویسید (مثلاً /usr/bin/mysqldump) یا PATH را ابتدای اسکریپت صریح تنظیم کنید.
- خروجی را لاگ کنید: انتهای هر خط کرون، خروجی و خطا را به فایل بفرستید:
>> /var/log/backup-cron.log 2>&1. کرونِ بیلاگ یعنی خرابیِ بیتاریخ؛ و همین فایلها را طبق راهنمای لاگ سرور در چرخش logrotate بگذارید تا خودشان دیسک را پر نکنند. - قفل علیه اجرای همزمان: اگر اجرای یک نوبت بیش از فاصلهٔ زمانبندی طول بکشد (بکاپ سنگین، پایگاهدادهٔ بزرگ)، نوبت بعدی روی قبلی سوار میشود و خرابی عجیب میسازد. پیشوند سادهاش:
flock -n /tmp/backup.lock /usr/local/bin/backup.shکه اگر نوبت قبل هنوز باز است، نوبت جدید را بیسروصدا رد میکند. - هشدار شکست، جدا از لاگ: لاگ را کسی هر روز نمیخواند. کارهای حیاتی (بکاپ، همگامسازی) باید در شکست، خودشان خبر بدهند؛ همان الگوی اسکریپت چندخطی + هشدار که در راهنمای مانیتورینگ و FAQ راهنمای لاگ گفتیم. قاعدهٔ طلایی: سکوتِ کرون را هرگز نشانهٔ سلامت نگیرید.
- اول دستی، بعد زمانبندی: هر اسکریپت را قبل از ثبت در crontab، یکبار با همان کاربر و ترجیحاً با محیط خالی تست کنید:
env -i /bin/sh -c '/usr/local/bin/backup.sh'رفتار واقعی زیر cron را بهتر از ترمینالِ پر از متغیرهای شما شبیهسازی میکند.
پنج کرونی که هر سایت جدی باید داشته باشد
اگر crontab سرورتان خالی است، این مجموعهٔ شروع، حاصل جمعِ همان راهنماهایی است که تا امروز نوشتهایم:
- بکاپ شبانه: فایلها و دیتابیس، با قفل flock و لاگ؛ و ارسال بستهٔ کامل به مقصد بیرونی طبق قانون ۳-۲-۱. ساعتش را از ساعت خلوت واقعی سایتتان بردارید، نه از عادت.
- چک سلامت هر پنج دقیقه: یک درخواست به صفحهٔ اصلی و یکی به صفحهٔ حیاتی (مثلاً پرداخت)؛ در خطا، هشدار. اگر سرویس پایش بیرونی دارید، این کرون پشتیبانِ داخلیِ همان است.
- پاکسازی هفتگی: فایلهای موقت، سشنهای منقضی و کشهای قدیمی؛ همان چیزهایی که بیسروصدا دیسک را میخورند و در قصهٔ «دیسکِ پر» راهنمای لاگ دیدیم.
- گزارش هفتگی به خودتان: چند خط خروجی df و فهرست بهروزرسانیهای معوق امنیتی، در یک ایمیل یا پیام؛ پنج دقیقه خواندن، جلوی دو حادثهٔ پرتکرار (دیسک پر و وصلهٔ عقبافتاده) را میگیرد.
- تمدیدچک ماهانه: روزهای ماندهٔ گواهی SSL و دامنه را چک و زیر آستانه هشدار بدهد؛ پشتیبانِ ماشینیِ همان تقویم تمدیدی که در راهنمای نگهداری ساختیم.
روی هاست اشتراکی که سطح دسترسی سیستمی ندارید، بخشی از این فهرست (مثل گزارش دیسک سرور) بر عهدهٔ میزبان است و بقیه را از همان Cron Jobs پنل هاست میسازید؛ روی سرور شخصی، هر پنج مورد مال شماست.
امنیت کرون؛ سه قاعدهٔ کوتاه
اول، کاربر درست: کرونِ هر سایت را با همان کاربر سایت اجرا کنید، و crontab روت را فقط برای کارهای واقعاً سیستمی نگه دارید؛ اسکریپتِ خراب یا نفوذی که زیر روت اجرا شود، کل سرور را میبرد. دوم، جای درست: اسکریپتهای کرون بیرون از وبروت بنشینند با مجوزِ فقط-مالک؛ اسکریپت بکاپِ داخل پوشهٔ عمومی، هم از وب قابلاجراست هم نامش در اسکن باتها دیده میشود (الگوی موج ۴۰۴ که در راهنمای لاگ گفتیم). سوم، رازهای بیرون از crontab: رمز دیتابیس و کلیدها را داخل خط crontab یا متن اسکریپت نگذارید؛ از فایل env جداگانه با مجوز محدود بخوانید تا خروجی crontab -l و لاگها، ناخواسته راز پخش نکنند.
قصهٔ تکراری تیکتها؛ بکاپی که سه ماه اجرا نشده بود
الگویی که در پشتیبانی بارها دیدهایم: مدیر سرور اسکریپت بکاپ را مینویسد، در ترمینال تست میکند، جواب میگیرد، در crontab میگذارد و با خیال راحت میرود. ماهها بعد، روز حادثه، پوشهٔ بکاپ تا همان هفتهٔ اول پر است و بعدش خالی. بازسازی ماجرا همیشه همان داستان است: چند روز بعد از تنظیم، جابهجایی سرور یا تغییری کوچک، مسیر یکی از فرمانها را عوض کرده؛ cron با PATH خالی فرمان را پیدا نکرده، خطا را در ایمیلِ سیستمیِ خواندهنشده گذاشته و تمام. سه قانون از پنج قانون بالا دقیقاً برای همین روز نوشته شدهاند: مسیر مطلق جلوی خرابی را میگرفت، لاگ تاریخ دقیق شکست را میگفت، و هشدارِ شکست، سه ماه را به سه ساعت تبدیل میکرد. اگر امروز فقط یک کار از این مقاله انجام میدهید، همین باشد: لاگ و هشدار را به کرونهای بکاپتان اضافه کنید؛ خودِ چیدمان بکاپ را هم با استراتژی بکاپ و قانون ۳-۲-۱ تنظیم کنید.

سوالات متداول دربارهٔ کرونجاب
کرون چه فرقی با «زمانبندی» افزونههای وردپرس دارد؟
بیشتر افزونههایی که ادعای زمانبندی دارند (بکاپ، انتشار، ایمیل) زیر پوست همان WP-Cron سوارند؛ یعنی همهٔ محدودیتهایی که بالاتر گفتیم (وابستگی به بازدید) را به ارث میبرند، فقط با ظاهر قشنگتر. با فعال کردن کرون واقعی، همهٔ این افزونهها هم یکجا قابلاعتماد میشوند؛ لازم نیست تکتکشان را عوض کنید. تنها استثنا افزونههاییاند که صریحاً میگویند از کرون سیستمی استفاده میکنند؛ آنها از اول مستقل بودهاند.
هاست اشتراکی هم کرونجاب دارد؟
بله؛ پنلهای رایج بخش Cron Jobs دارند و برای بیشتر نیازها (بکاپ، WP-Cron واقعی، پاکسازی) کاملاً کافی است. دو محدودیت معمول دارد: حداقل فاصلهٔ زمانی (مثلاً کوتاهتر از پنج دقیقه مجاز نیست) و سهمیهٔ منابع، یعنی کار سنگین نیمهشب هم نباید همسایهها را کند کند. اگر کرونهایتان سنگین و متعدد شدهاند، این خودش یکی از نشانههای رسیدن به سرور مجازی است.
از کجا بفهمم کرونم واقعاً اجرا میشود؟
سه لایه: فایل لاگی که خودتان در انتهای خط کرون ساختهاید (تاریخ آخرین نوشته را ببینید)، لاگ سیستمیِ cron که اجرا شدن یا نشدن هر خط را ثبت میکند، و برای کارهای حیاتی، اثرِ خروجی (تاریخ آخرین فایل بکاپ). سادهترین تست سلامت هم این است: موقتاً زمانبندی را روی «دو دقیقهٔ بعد» بگذارید و اجرای واقعی را یکبار با چشم ببینید.
WP-Cron را روی هر سایتی غیرفعال کنیم؟
فقط وقتی جایگزین واقعیاش را ساختهاید. DISABLE_WP_CRON بدون آن خط crontab، یعنی خاموش کردن کامل زمانبندی وردپرس؛ پست زمانبندیشده، بکاپ افزونهای و بهروزرسانیهای خودکار همه میخوابند. ترتیب درست: اول کرون واقعی را بسازید و تستش کنید، بعد شبهکرون را خاموش کنید.
ساعت کرون با ساعت ایران نمیخواند؛ چرا؟
cron با ساعت و منطقهٔ زمانی خود سرور کار میکند، و سرورها اغلب روی UTC تنظیماند. قبل از نوشتن زمانبندی، با فرمان date ساعت سرور را ببینید و اختلاف را حساب کنید؛ «۰۳:۳۰ شب» روی سرور UTC یعنی هفت صبح تهران. تغییر منطقهٔ زمانی سرور هم شدنی است، ولی اگر چند سرویس روی آن کار میکند، محاسبهٔ اختلاف امنتر از جابهجایی ساعت کل سرور است.
برای چند سایت روی یک سرور، کرونها را چطور نظم بدهم؟
سه عادت کوچک، نظم بزرگ میسازد: هر سایت اسکریپتها و لاگ خودش را در پوشهٔ خودش داشته باشد؛ بالای هر خط crontab یک خط کامنت بنویسید که این کار چیست و مال کدام سایت است؛ و زمانهای شروع را پلهای بچینید (۰۳:۰۰، ۰۳:۲۰، ۰۳:۴۰) تا همهٔ بکاپها همزمان منابع را نبلعند؛ همان منطقی که در راهنمای منابع سرور برای پیک مصرف گفتیم.
MAILTO چیست و ایمیلهای کرون کجا میروند؟
cron بهصورت پیشفرض، هر خروجی و خطای کارها را به صندوق ایمیلِ محلی کاربر سرور میفرستد؛ صندوقی که تقریباً هیچکس بازش نمیکند و همانجاست که خطاها سه ماه بیصدا میمانند. با گذاشتن MAILTO=you@example.ir در ابتدای crontab میتوانید مقصد را آدرس واقعی خودتان کنید، به شرطی که ارسال ایمیل سرور درست پیکربندی شده باشد. ترکیب عملیتر، همان توصیهٔ قوانین بالاست: خروجی به فایل لاگ، و هشدار شکست از مسیر مطمئن خودتان.
روی سرور ویندوز معادل کرون چیست؟
Task Scheduler همان نقش را دارد: زمانبندی اجرای اسکریپت با همان منطق دقیقه/ساعت/روز، بهعلاوهٔ امکاناتی مثل اجرای معوق بعد از روشن شدن. قواعد این مقاله عیناً منتقل میشود: مسیر مطلق، لاگ خروجی، جلوگیری از اجرای همزمان و تست دستی؛ فقط نحو فرق دارد و زمانبندی از پنجرهٔ گرافیکی تعریف میشود، نه فایل متنی.
کار پیچیدهتر از کرون دارم (صف، تکرار در شکست)؛ چه کنم؟
cron آغازگرِ خوب است، مدیرِ فرایند معمولی. وقتی نیازتان به تکرار خودکار در شکست، وابستگی بین کارها یا صف رسید، به ابزار سطح بالاتر فکر کنید: systemd timers روی سرور خودتان، یا صف کارِ خود اپلیکیشن. قاعدهٔ ساده: cron را برای «سر ساعت شروع کن» نگه دارید و منطقِ «اگر شکست خورد چه» را داخل اسکریپت یا ابزار بالاتر ببرید.




