Cron job'ı kaydettiniz, crontab -l de onu gösteriyor, ama hiçbir şey olmuyor. Ne bir e-posta geliyor, ne bir dosya oluşturuluyor, ne de bir log yazılıyor. Sadece sessizlik. Bu sessizlik meselenin en tehlikeli kısmı, çünkü cron varsayılan olarak hiçbir hatayı sizin görebileceğiniz bir yere kaydetmez. Bu durumda yapmanız gereken şey job'ı yeniden yazmak değil; cron'un gerçekten çalışıp çalışmadığını anlamaktır.
Önce cron job'ın çalışıp çalışmadığını kanıtlayın
Herhangi bir değişiklikten önce, ana betiğe hiçbir bağımlılığı olmayan bir test job'ı oluşturun:
*/1 * * * * /bin/date >> /tmp/cron-test.log 2>&1
Bir dakika bekleyin ve ardından cat /tmp/cron-test.log komutunu çalıştırın. Dosya dolduysa, cron servisi sağlıklıdır ve sorun betiğinizin içindedir. Dosya oluşturulmadıysa, sorun servis katmanındadır: ya sunucuda crond çalışmıyor, ya da giriş yaptığınız kullanıcı ile cron'un kayıtlı olduğu kullanıcı aynı değil.
Burada şu hata yapılır: kullanıcı sudo crontab -e ile job'ı root tablosuna kaydeder, sonra normal kullanıcıyla çıktı dosyasını kontrol eder ve dosya olmadığı için cron'un bozuk olduğu sonucuna varır. Aslında job çalışmıştır, ama root yetkisiyle ve başka bir yola yazmıştır. Her zaman crontab -l -u username ile job'ın tam olarak hangi kullanıcı adı altında olduğunu kontrol edin.
Mutlak yol, cron job'ın sessiz katili
Cron neredeyse boş bir ortamla çalışır. PATH genellikle sadece /usr/bin:/bin'dir ve HOME veya SHELL gibi değişkenler ayarlanmamış olabilir. Yani betikte python3 manage.py yazdığınızda, cron python3'ün nerede olduğunu bilmez, çünkü onun PATH'inde değildir. Hata da bir yere gitmez.
Çözüm basittir: crontab'ın başında açık bir PATH tanımlayın ve job'ın kendisinde de binary'nin tam yolunu yazın.
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
*/5 * * * * /usr/bin/php /home/user/public_html/cron.php >> /home/user/cron.log 2>&1
Daha az söylenen bir nokta: crontab'da % özel bir anlam taşır ve newline'a dönüşür. Job komutunda date +%Y-%m-%d kullanırsanız, cron onu parçalara ayırır ve komut garip bir hatayla başarısız olur. % işaretini ters eğik çizgiyle kaçırmanız gerekir: date +\%Y-\%m-\%d.
Çıktıyı nereye gönderiyorsunuz?
Cron her standart çıktıyı ve her standart hatayı kullanıcının yerel e-postasına gönderir. Sunucuda MTA kurulu değilse, o e-posta kuyrukta bekler veya atılır ve siz hiçbir zaman haberdar olmazsınız. İki yolunuz var: ya çıktıyı bir dosyaya gönderin, ya da syslog'a pompalayın.
*/10 * * * * /home/user/backup.sh 2>&1 | /usr/bin/logger -t mycron
Sonra journalctl -t mycron -f veya grep mycron /var/log/syslog ile hatayı canlı görün. Bu yöntem, betiğinizin birkaç aşaması olduğunda ve hangi aşamanın kırıldığını bilmediğinizde değerlidir. Bedeli, logların diskte birikmesidir ve log rotasyonu (logrotate) yoksa birkaç ay sonra bölüm alanını doldururlar. Sık çalışan job'lar için log dosyasını logrotate ile yönetin veya rotasyonu kendisi yapan logger kullanın.
WordPress cron job neden çalışmıyor
WordPress'te hikaye bir katman daha karmaşıktır. WordPress varsayılan olarak wp-cron.php kullanır ki bu ne gerçek bir cron'dur ne de bir garantisi vardır; sadece bir ziyaretçi siteye geldiğinde çalışır. Site trafiği düşükse veya site önbelleğe alınmışsa, zamanlanmış job'lar saatlerce geri kalır. İşareti de şudur: zamanlanmış e-postalar gecikmeli gelir veya yedekleme eklentileri hiç çalışmaz.
Doğru yol, wp-cron'u devre dışı bırakıp onu gerçek bir sistem cron'uyla değiştirmektir. Önce wp-config.php dosyasına şu satırı ekleyin:
define('DISABLE_WP_CRON', true);
Sonra her beş dakikada bir WP-CLI ile çalışan bir sistem job'ı oluşturun:
*/5 * * * * /usr/local/bin/wp cron event run --due-now --path=/home/user/public_html --quiet
WP-CLI'ye aşina değilseniz, terminale WordPress yönetimi için gerekli WP-CLI komutları iyi bir başlangıç noktasıdır. Ve sorunun cron'da mı yoksa WordPress'in kendisinde mi olduğundan emin değilseniz, WordPress wp-cron rehberi bu ikisinin farkını örneklerle gösterir.
Daha az baktığınız birkaç neden
- Çalıştırma izni: Betiğin
chmod +xolması gerekir, yoksa cron "Permission denied" hatasıyla sessizce ölür. - Windows satır sonu: Dosyayı bir Windows düzenleyiciyle kaydettiyseniz, ilk satırın sonundaki
\r\n, cron'un binary adını fazladan bir karakterle okumasına ve başarısız olmasına neden olur.file script.shveyacat -Aile kontrol edin. - Dosya kilidi: Önceki çalışma henüz bitmemişse ve sonraki job gelirse, iki kopya aynı dosya üzerinde aynı anda çalışır.
flockile bunu önleyin. - Saat dilimi: Cron sistem saatini kullanır, sizin yerel saatinizi değil. Sunucu UTC'deyse ve siz job'ı Tahran saatiyle sabah 2'ye ayarladıysanız, altı buçuk saat farkınız var.
Kritik job'lar için flock'u ciddiye alın:
*/15 * * * * /usr/bin/flock -n /tmp/backup.lock /home/user/backup.sh
-n anahtarı, kilit serbest değilse çalıştırma ve sessizce geç anlamına gelir. Bu tam olarak yedekleme için istediğiniz doğru davranıştır.
Hangi yöntemi seçmeliyim?
| Yöntem | Uygun olduğu durum | Ödediğiniz bedel |
|---|---|---|
| Kullanıcı crontab'ı | Kişisel betikler, yedekleme, geçici dosya temizliği | Boş ortam, mutlak yol gereksinimi |
| systemd timer | Yapılandırılmış log ve retry gerektiren job'lar | Unit file yazmak, daha fazla karmaşıklık |
| WordPress wp-cron | Kritik olmayan job'lara sahip yüksek trafikli siteler | Güvenilmez ve ziyarete bağlı çalışma |
| Sistem cron + WP-CLI | Zamanlamanın önemli olduğu her WordPress sitesi | SSH erişimi ve ilk kurulum gereksinimi |
Tek bir seçim yapacak olsam, her kritik job için systemd timer'ı tercih ederim, çünkü journalctl her çalışmanın çıktısını timestamp ile saklar ve OnCalendar test edilebilir. Ancak günlük işlerin %90'ı için crontab yeterlidir ve daha hızlı devreye girer. Sadece yolları mutlak yazın ve çıktıyı sonradan okuyabileceğiniz bir yere gönderin.
Paylaşımlı hosting'deyseniz ve systemd veya sistem loglarına erişiminiz yoksa, seçenekleriniz daha sınırlıdır. Linux hosting'te genellikle crontab yönetim panelinden ayarlanabilir ve aynı mutlak yol ve çıktı yönlendirme kuralları geçerlidir. Sorunun ağdan mı yoksa DNS'ten mi kaynaklandığını hızlıca kontrol etmek için, ServerNet'in ücretsiz araçları işi kısaltır ve bir DNS hatası görürseniz, DNS_PROBE_FINISHED_NXDOMAIN hata rehberi teşhis yolunu adım adım açıklamıştır.
Sık sorulan sorular
Cron job'ım neden crontab -l'de görünüyor ama çalışmıyor?
En yaygın neden, cron ortamında PATH'in boş olmasıdır. Cron, sizin etkileşimli shell'inizden çok daha kısıtlı bir ortamla çalışır ve python3 veya node gibi binary'leri bulamaz. Binary'nin tam yolunu job'da yazın ve crontab'ın başına bir PATH= satırı ekleyin.
İkinci neden, job'ın yanlış kullanıcı altında kaydedilmesidir. crontab -l -u username ile job'ın tam olarak hangi kullanıcı için kaydedildiğini kontrol edin ve çıktı dosyasını aynı kullanıcıyla okuyun.
Cron job'ın çalıştığını ama hata verdiğini nasıl anlarım?
Çıktı ve standart hatayı bir dosyaya yönlendirin: >> /home/user/cron.log 2>&1. Bu yönlendirme olmadan, cron çıktıyı yerel e-postaya gönderir ve MTA kurulu değilse onu kaybedersiniz. Sık çalışan job'lar için, logger'a göndermek ve journalctl ile okumak daha temizdir.
WordPress wp-cron gerçek cron'un yerini alır mı?
Hayır. wp-cron sadece biri siteyi ziyaret ettiğinde çalışır, bu yüzden düşük trafikli veya önbelleğe alınmış sitelerde job'lar büyük gecikmeyle çalışır. Güvenilir zamanlama için DISABLE_WP_CRON'u true yapın ve WP-CLI ile bir sistem job'ı oluşturun.
crontab ile systemd timer arasındaki fark nedir ve hangisini seçmeliyim?
crontab daha basittir ve çoğu iş için yeterlidir, ancak yapılandırılmış log ve retry mekanizması yoktur. systemd timer her çalışmanın çıktısını journal'da saklar, servisler arası bağımlılığı destekler ve zamanlaması systemd-analyze calendar ile test edilebilir. Kritik bir job'ınız varsa ve son çalışmanın başarılı olup olmadığını bilmeniz gerekiyorsa, systemd timer doğru seçimdir.
Sonraki adım: hemen şimdi /bin/date ile bir test job'ı oluşturun ve çıktısının bir yere yazıldığından emin olun. Bu döngü kapanana kadar, eklediğiniz her diğer job sadece bir tahmindir.
Yorumlar 0
Henüz yorum yok — ilk siz olun!