پاسخ کوتاه: کرون جاب یک خط تنظیمات است که به لینوکس می گوید «این دستور را در این دقیقه/ساعت/روز اجرا کن». برای بکاپ روزانه، پاک سازی لاگ و کارهای تکرارشونده از آن استفاده می شود. سه چیزی که بیشتر خراب می کند: مسیر نسبی به جای مسیر کامل، محیط خالی (PATH و متغیرها) و نبودن لاگ برای دیدن نتیجه. پیش از زمان بندی، مطمئن شوید هاست اجازهٔ اجرای اسکریپت و دسترسی به دیتابیس را می دهد. بکاپ بخشی از امنیت سایت است، نه یک کار جانبی.
کرون جاب دقیقاً چیست
سرویس cron در لینوکس یک زمان بند است. هر کاربر یک فایل زمان بندی جدا دارد و با crontab -e ویرایش می شود. هر خط پنج فیلد زمانی دارد و بعد از آن دستوری که باید اجرا شود:
دقیقه ساعت روز-ماه ماه روز-هفته دستور
0 3 * * * /usr/bin/...
ستاره یعنی «هر مقدار». عدد یعنی همان مقدار. فهرست با کاما جدا می شود (0,30) و بازه با خط تیره نوشته می شود (1-5). فیلد پنجم روز هفته است: ۰ یکشنبه و ۶ شنبه.
سه مثال که در عمل استفاده می شود
0 3 * * *— هر روز ساعت ۳ بامداد*/10 * * * *— هر ده دقیقه0 4 * * 6— هر شنبه ساعت ۴ بامداد (بکاپ هفتگی)
نکته ای که تازه کارها را زمین می زند: ساعت کرون بر اساس ساعت سرور است، نه ساعت شما. اگر سرور UTC باشد و شما در تهران، ساعت ۳ بامداد سرور یعنی ۶:۳۰ صبح تهران. با timedatectl یا date ساعت سرور را ببینید. روی سرور اشتراکی، جاب های سنگین را به ساعت کم ترافیک ببرید.
تست واقعی روی همین سرور
برای اینکه حرف در حد ادعا نماند، همین حالا یک جاب هر دقیقه نصب کردم و نتیجه را خواندم. اول یک خط اضافه شد:
printf '%s\n' \
"* * * * * /bin/date >> /tmp/cron-probe.log" \
| crontab -
بعد از حدود یک دقیقه، فایل لاگ این را داشت:
Sun Nov 1 09:15:01 AM UTC 2026
یعنی جاب اجرا شده است. دو چیز از همین تست معلوم می شود: ساعت سرور UTC است و مسیر کامل /bin/date کار می کند. بعد از تست، زمان بندی پاک شد:
crontab -r
crontab -l # no crontab for hermes
پنج خطای رایج و نشانهٔ هرکدام
| نشانه | علت | راه حل |
|---|---|---|
| جاب اجرا می شود ولی فایل ساخته نمی شود | مسیر نسبی در دستور | مسیر کامل بنویسید (/usr/bin/php نه php) |
| دستور در ترمینال کار می کند، در کرون نه | PATH در کرون خالی است | در ابتدای crontab مقدار PATH را تعیین کنید |
| اسکریپت به متغیر محیطی دسترسی ندارد | کرون فایل پروفایل را نمی خواند | متغیرها را داخل خود اسکریپت یا crontab تعریف کنید |
| هیچ خطایی دیده نمی شود | خروجی به هیچ جا نمی رود | انتهای دستور >> /var/log/job.log 2>&1 بگذارید |
| جاب دوبار اجرا می شود | دو خط تکراری یا cron سیستمی و کاربری هم زمان | crontab -l و ls /etc/cron.d را چک کنید |
بکاپ روزانه: یک اسکریپت که واقعاً کار می کند
اسکریپت را در مسیر ثابت بگذارید و اجراپذیر کنید. این نمونه دیتابیس را می گیرد، فایل ها را فشرده می کند و قدیمی ها را پاک می کند:
#!/bin/bash
set -euo pipefail
DATE=$(date +%F)
DIR=/var/backups/site
mkdir -p "$DIR"
mysqldump --single-transaction \
-u USER -pPASS DB > "$DIR/db-$DATE.sql"
tar -czf "$DIR/files-$DATE.tar.gz" /var/www/site
find "$DIR" -type f -mtime +14 -delete
سه نکتهٔ مهم: --single-transaction جدول ها را قفل نمی کند، رمز دیتابیس نباید داخل دستور باشد (از فایل تنظیمات با دسترسی ۶۰۰ استفاده کنید)، و -mtime +14 یعنی فایل های قدیمی تر از دو هفته پاک شوند. یک بار دستی اجرا کنید؛ اگر خطا داد، کرون هم همان خطا را می دهد.
زمان بندی:
0 3 * * * /usr/local/bin/backup.sh \
>> /var/log/backup.log 2>&1
پاک سازی لاگ ها بدون خراب کردن سیستم
لاگ ها بی صدا بزرگ می شوند. برای پاک کردن فایل های قدیمی به جای rm روی مسیر باز، از find استفاده کنید:
find /var/log -type f -name "*.log" -mtime +30 -delete
برای سرویس هایی که لاگ را باز نگه می دارند، چرخش لاگ بهتر از حذف است. اگر مطمئن نیستید، اول با -print به جای -delete اجرا کنید تا ببینید چه چیزی حذف می شود.
چطور بفهمیم جاب اجرا شده
سه جا را چک کنید: فایل لاگی که خودتان تعیین کرده اید، لاگ سیستم (grep CRON /var/log/syslog در دبیان و اوبونتو) و خروجی خود دستور. اگر در crontab مقدار MAILTO تعیین شده باشد، خروجی خطاها به ایمیل می رود؛ روی سرور بدون ایمیل، این خروجی عملاً گم می شود و همان دلیل «هیچ اتفاقی نیفتاد» است.
اجرای هم زمان: مشکل خاموش بکاپ های سنگین
اگر بکاپ یک بار ۴۰ دقیقه طول بکشد و جاب هر ۳۰ دقیقه تنظیم شده باشد، نسخهٔ دوم روی اولی می افتد و هر دو نیمه کاره می مانند. راه حل استاندارد flock است: تا وقتی اجرای قبلی تمام نشده، اجرای تازه وارد نمی شود.
*/30 * * * * /usr/bin/flock -n \
/var/lock/backup.lock /usr/local/bin/backup.sh
گزینهٔ -n یعنی اگر قفل گرفته شده بود، بی صدا رد شو؛ بدون آن، جاب در صف می ماند. این یک خط، بیشتر از هر تنظیم دیگری از بکاپ های نیمه کاره جلوگیری می کند.
کرون در برابر systemd timer
| ویژگی | کرون | systemd timer |
|---|---|---|
| سادگی | یک خط | دو فایل (service و timer) |
| لاگ | باید خودتان بگذارید | در journal ثبت می شود |
| اجرای دوباره پس از خطا | ندارد | دارد |
| انتقال بین سرورها | کپی crontab کافی است | نیاز به کپی دو فایل |
برای بکاپ روزانه و پاک سازی، کرون کافی و قابل انتقال تر است. اگر جابی دارید که «اگر شکست خورد بعد از ده دقیقه دوباره تلاش کن»، systemd timer دست بالا دارد.
کرون و لاراول: کاری که خیلی ها اشتباه می کنند
در لاراول نباید برای هر تسک یک خط کرون نوشت. یک خط کافی است و خود لاراول زمان بندی را مدیریت می کند:
* * * * * cd /var/www/site \
&& php artisan schedule:run \
>> /var/log/scheduler.log 2>&1
شرطش این است که تسک ها در routes/console.php یا app/Console/Kernel.php تعریف شده باشند. اگر این خط نباشد، schedule:run هیچ وقت اجرا نمی شود و هیچ خطایی هم نمی بینید — یکی از رایج ترین دلایل «کرون کار نمی کند» در پروژه های لاراول همین است.
تست بازیابی: بخشی که همیشه جا می افتد
بکاپی که بازیابی نشده، بکاپ نیست. ماهی یک بار روی یک سرور تست، فایل را باز کنید و دیتابیس را برگردانید:
gunzip -c files-2026-11-01.tar.gz | tar -tf - | head
mysql -u USER -p TEST_DB < db-2026-11-01.sql
اگر جدول ها و تعداد رکوردها درست برگشتند، بکاپ سالم است. این کار پنج دقیقه وقت می گیرد و تنها راه اطمینان است.

چک لیست پذیرش
- دستور با مسیر کامل نوشته شده است.
- یک بار دستی اجرا شده و خروجی اش درست است.
- لاگ دارد و بعد از اجرای زمان بندی، فایل لاگ تغییر کرده است.
- ساعت سرور بررسی شده و ساعت اجرا با تهران تفاوت دارد.
- نسخهٔ پشتیبان یک بار بازیابی شده است، نه فقط گرفته شده.
ساعت سرور و منطقهٔ زمانی
پیش از نوشتن هر زمان بندی، ساعت سرور را ببینید:
timedatectl
date
اگر خروجی Time zone: UTC بود و شما در تهران هستید، هر ساعت اجرا ۳:۳۰ زودتر از تصور شما رخ می دهد. دو راه دارید: منطقهٔ زمانی سرور را تغییر دهید (روی سرورهایی که چند اپلیکیشن دارند توصیه نمی شود) یا زمان بندی را بر اساس UTC بنویسید و در توضیح جاب بنویسید «۳ بامداد UTC یعنی ۶:۳۰ تهران». راه دوم کم ریسک تر است، چون تغییر منطقهٔ زمانی می تواند لاگ ها و زمان بندی های موجود را جابه جا کند.
چند جاب روی یک سرور: نظم نگه داشتن
وقتی تعداد جاب ها از پنج بیشتر شد، crontab بدون توضیح تبدیل به چیزی می شود که هیچ کس جرات دست زدن به آن را ندارد. سه قاعدهٔ ساده:
- بالای هر خط یک کامنت با تاریخ و دلیل بنویسید.
- برای هر کار یک اسکریپت در
/usr/local/binبگذارید، نه دستور طولانی داخل crontab. - همهٔ لاگ ها را در یک پوشه جمع کنید تا پیدا کردنشان ساده باشد.
# 2026-11-01 backup - daily 03:00 UTC
0 3 * * * /usr/local/bin/backup.sh \
>> /var/log/jobs/backup.log 2>&1
پاک سازی لاگ و چرخش آن
حذف فایل لاگ در حالی که سرویس آن را باز نگه داشته، فضای دیسک را آزاد نمی کند؛ فقط نام فایل را پاک می کند و سرویس همچنان به فایل قدیمی می نویسد. راه درست، چرخش لاگ است. ابزار logrotate از قبل روی اکثر سرورها نصب است و با یک فایل تنظیمات، لاگ را روزانه می چرخاند و قدیمی ها را می بندد. اگر خودتان دستی لاگ می نویسید، همان find -mtime کافی است، ولی برای لاگ سرویس ها از logrotate استفاده کنید.
یک قاعدهٔ ساده برای اندازه گیری: اگر جاب شما بیشتر از پنج دقیقه طول می کشد، حتماً لاگ و قفل داشته باشد؛ اگر کمتر است، یک خط و یک لاگ کافی است. پیچیدگی اضافه، خودش منبع خطاست.
کرون جاب در cPanel و دایرکت ادمین
اگر سایت روی هاست اشتراکی است، لازم نیست به ترمینال دسترسی داشته باشید. در cPanel از بخش Advanced > Cron Jobs همان پنج فیلد را می بینید: دقیقه، ساعت، روز، ماه و روز هفته، به علاوهٔ یک کادر Command. مستندات cPanel تاکید می کند هر پنج فیلد باید پر شوند و بعد از ذخیره، خط در فهرست پایین صفحه اضافه می شود. گزینهٔ Common Settings هم چند بازهٔ آماده (روزانه، هفتگی، ماهانه) می گذارد که همان پنج فیلد را برایتان پر می کند.
در دایرکت ادمین مسیر Advanced Features > Cron Jobs است و همان پنج فیلد را با کادر Command می پرسد. تفاوت مهم: در پنل های اشتراکی، دستور با کاربر هاست اجرا می شود، نه root؛ پس دستوری که به دسترسی مدیریتی نیاز دارد همان جا شکست می خورد و باید با مسیر کامل و مجوز درست نوشته شود.
یک نکتهٔ عملی که در پنل ها زیاد دیده می شود: خروجی دستور در پنل به ایمیل کاربر هاست می رود. اگر ایمیل تنظیم نشده باشد، خطاها گم می شوند؛ همان اول یک تغییر مسیر به فایل اضافه کنید.
WP-Cron و تفاوتش با کرون واقعی
وردپرس زمان بند خودش را دارد به نام WP-Cron که با هر بازدید صفحه بررسی می شود، نه با ساعت سرور. یعنی اگر سایت بازدیدکننده نداشته باشد، انتشار زمان بندی شده و بکاپ های وردپرسی هم عقب می افتند. راه استاندارد، خاموش کردن آن و سپردن کار به کرون واقعی است: در wp-config.php مقدار DISABLE_WP_CRON را true کنید و بعد یک خط کرون بگذارید که هر پانزده دقیقه همان فایل را صدا بزند.
*/15 * * * * curl -s \
https://example.com/wp-cron.php?doing_wp_cron \
> /dev/null 2>&1
این کار دو فایده دارد: زمان بندی به بازدید وابسته نیست و بار پردازش از صفحهٔ کاربر برداشته می شود. اگر این تفاوت را نمی دانستید، احتمالاً بکاپ وردپرسی تان هم تا حالا با تاخیر اجرا می شده است.
پرسش های متداول
هر دقیقه اجرا شود اشکال دارد؟ برای کارهای سبک نه؛ برای بکاپ و اسکریپت سنگین بله، بار سرور را بالا می برد.
کرون یا systemd timer؟ کرون ساده تر و قابل انتقال تر است؛ systemd برای لاگ و وابستگی ها بهتر است. برای بکاپ روزانه، کرون کافی است.
اگر سرور ری استارت شود چه می شود؟ زمان بندی می ماند؛ خود cron باید در بوت فعال باشد.

ارسال نظر جدید