Bir sunucuda gece 03.00'te kimse uyanık değilken bir yedekleme betiği kendiliğinden çalışır. Disk dolduğunda eski loglar otomatik silinir. Ayın ilk günü bir rapor kendi kendine oluşur. Bunların hepsini Linux'ta cron yapar. On yıllardır aynı mantıkla çalışan bu zamanlayıcı, sunucu otomasyonunun hâlâ temel taşlarından biri. Bu yazıda crontab söz dizimini gerçek örneklerle, sık yapılan hatalarla birlikte anlatıyoruz.
Cron'un çalışma mantığı basittir: arka planda sürekli açık duran bir servis, cron daemon, her dakika crontab dosyalarını kontrol eder ve zamanı gelen görevleri çalıştırır. Bu yazı önce söz dizimini, ardından yönetim komutlarını, son olarak da gerçek kullanımda sık karşılaşılan tuzakları ele alıyor.
Crontab Sözdizimi
Her cron satırı beş zaman alanından ve ardından çalıştırılacak komuttan oluşur: dakika, saat, ayın günü, ay ve haftanın günü. Crontab dosyasını düzenlemek için şu komut kullanılır:
crontab -e
Örnek bir satır şöyle görünür:
# Her gün saat 03:30'da yedekleme betiğini çalıştır
30 3 * * * /home/kullanici/scripts/yedekle.sh
Yıldız işareti "her" anlamına gelir; o alanda hangi değer gelirse gelsin görev çalışır. Aşağıdaki tablo en sık kullanılan zamanlama kalıplarını gösteriyor:
| İfade | Anlamı |
|---|---|
*/15 * * * * | Her 15 dakikada bir |
0 * * * * | Her saat başı |
0 9 * * 1-5 | Hafta içi her gün saat 09:00 |
0 0 1 * * | Her ayın ilk günü gece yarısı |
0 2 * * 0 | Her pazar saat 02:00 |
Eğik çizgi (/) aralıklı tekrarı belirtir, virgül (,) bir liste tanımlar, tire (-) ise bir aralık tanımlar. Örneğin 0 9,13,17 * * * ifadesi günde üç kez, saat 09.00, 13.00 ve 17.00'de çalışır.
Crontab Yönetimi
Mevcut görevleri listelemek, düzenlemek veya tamamen silmek için üç komut yeterlidir.

crontab -l # Mevcut cron job'ları listele
crontab -e # Düzenle
crontab -r # Tümünü sil (dikkatli kullanın)
Her satırın başına kısa bir açıklama yorumu eklemek, altı ay sonra aynı crontab dosyasına bakıldığında hangi görevin ne işe yaradığını hatırlatır. Görev sayısı arttıkça bu küçük alışkanlık zaman kazandırır.
Cron, varsayılan olarak bir görevin çıktısını sistem kullanıcısına e-posta ile göndermeye çalışır. Çoğu sunucuda mail sunucusu kurulu olmadığı için bu e-postalar hiçbir yere ulaşmadan kaybolur. Çıktıyı doğrudan bir log dosyasına yönlendirmek daha güvenilirdir:
30 3 * * * /home/kullanici/scripts/yedekle.sh >> /var/log/yedekle.log 2>&1
2>&1 ifadesi hata çıktısını da aynı log dosyasına yönlendirir. Böylece betik başarısız olduğunda hatanın tamamı log dosyasında görünür.
Özel Zamanlama Kısayolları
Sık kullanılan zamanlama kalıpları için cron, beş alanlı ifadeyi yazmadan kullanılabilecek kısayollar sunar:
@daily /home/kullanici/scripts/temizlik.sh # Her gün gece yarısı
@hourly /home/kullanici/scripts/kontrol.sh # Her saat başı
@reboot /home/kullanici/scripts/baslangic.sh # Sistem her açıldığında
@reboot, sistem yeniden başladığında otomatik çalışması gereken betikler için kullanışlıdır; bir servisi ayağa kaldırmak veya geçici dosyaları temizlemek gibi durumlarda sık tercih edilir. Bu kısayollar, özellikle görev sayısı fazla olan crontab dosyalarında beş rakamı zihinden çözmeden anlamı doğrudan gösterir.
Ortam Değişkenleri ve Sık Yapılan Hata
Cron job'larla ilgili en yaygın şikâyet şudur: "Betik terminalde çalışıyor ama cron'da çalışmıyor." Sebebi neredeyse her zaman aynıdır: cron, betiği çok sınırlı bir ortam değişkeni kümesiyle çalıştırır ve PATH değişkeni normal oturumdakinden çok daha kısadır. Betik içinde python3 ya da node gibi bir komut tam yol belirtilmeden çağrılıyorsa, cron o komutu bulamayabilir.

Çözüm, hem betik içinde hem crontab satırında her zaman mutlak yol kullanmaktır:
# Yanlış: cron ortamında "node" bulunamayabilir
* * * * * node /home/kullanici/app/betik.js
# Doğru: tam yol belirtilmiş
* * * * * /usr/bin/node /home/kullanici/app/betik.js
Komutun tam yolunu bulmak için which node veya command -v node komutları yeterlidir. Bir betiğin içindeki göreli dosya yolları da aynı sorunu yaşayabilir; betiğin başına cd /home/kullanici/proje satırı eklemek, çalışma dizininin cron ortamında da doğru olmasını sağlar. Gerekirse crontab dosyasının başında PATH değişkeni de açıkça tanımlanabilir:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Loglama ve Hata Ayıklama
Bir cron job'ın sessizce başarısız olması en tehlikeli senaryolardan biridir; kimse fark etmeden haftalar geçebilir. Betiğin başına ve sonuna zaman damgalı log satırları eklemek, sorun çıktığında nereden başlanacağını gösterir.

#!/bin/bash
echo "$(date): Yedekleme başladı" >> /var/log/yedekle.log
rsync -av /var/www/ /backup/www/
echo "$(date): Yedekleme bitti, çıkış kodu $?" >> /var/log/yedekle.log
Sistem genelindeki cron etkinliğini görmek için journalctl kullanılabilir:
sudo journalctl -u cron --since today
Bir görevi crontab'a eklemeden önce terminalde manuel çalıştırıp doğru sonucu verdiğinden emin olmak, cron ortamındaki farklardan doğan sürprizleri azaltır. Betik hata kodu döndürüyorsa bunu log'a yazmak, "çalıştı ama başarısız oldu" durumunu "hiç çalışmadı" durumundan ayırt etmeyi sağlar.
Cron ve systemd Timer Karşılaştırması
Modern Linux dağıtımlarında systemd kendi zamanlama mekanizmasını da içerir: systemd timer'lar. Bu iki araç aynı işi farklı biçimlerde yapar ve hangisinin uygun olduğu senaryoya göre değişir.
| Özellik | cron | systemd timer |
|---|---|---|
| Kurulum karmaşıklığı | Düşük, tek satır | Orta, iki dosya (.service + .timer) |
| Log entegrasyonu | Manuel yönlendirme gerekir | journalctl ile otomatik |
| Bağımlılık yönetimi | Yok | Var (başka servise bağlı çalıştırma) |
| Yaygınlık | Her Linux sisteminde var | systemd tabanlı dağıtımlarda var |
Basit, tek satırlık bir zamanlama ihtiyacı için cron hâlâ en hızlı çözümdür. Bir görevin başka bir servisin başlamasını beklemesi gerekiyorsa ya da ayrıntılı log takibi önemliyse, systemd timer daha uygun bir seçim olabilir.
Bir systemd timer örneği iki ayrı dosyadan oluşur. Önce /etc/systemd/system/yedekle.service dosyasında ne çalıştırılacağı tanımlanır:
[Unit]
Description=Günlük yedekleme
[Service]
ExecStart=/home/kullanici/scripts/yedekle.sh
Ardından /etc/systemd/system/yedekle.timer dosyasında ne zaman çalışacağı belirtilir:
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Timer'ı etkinleştirmek için:
sudo systemctl enable --now yedekle.timer
Persistent=true ayarı, sunucu kapalıyken zamanı gelen bir görevi sistem yeniden açıldığında otomatik çalıştırır. Cron'da aynı davranışı elde etmek için ayrı bir betik yazmak gerekir. Bu fark, sık kapanıp açılan geliştirme makinelerinde systemd timer'ı avantajlı kılar.
Gerçek Dünya Kullanım Örnekleri
En yaygın cron kullanımı otomatik yedekleme. Aşağıdaki satır her gece verileri uzak bir sunucuya kopyalar:
0 2 * * * /usr/bin/rsync -avz /var/www/ yedek-sunucu:/backup/www/ >> /var/log/rsync.log 2>&1
Log döndürme de klasik bir cron görevidir; her hafta eski logları sıkıştırıp arşivlemek disk alanını korur. SSL sertifikası yenileme de cron ile sık otomatikleştirilir; örneğin Let's Encrypt sertifikalarını otomatik yenilemek için:
0 3 * * * /usr/bin/certbot renew --quiet
Cron job yazarken göz önünde bulundurulması gereken birkaç temel kural var:
- Betik ve komutlar için her zaman mutlak yol kullanın
- Çıktıyı ve hataları bir log dosyasına yönlendirin
- Betiği crontab'a eklemeden önce manuel test edin
- Her satıra kısa bir açıklama yorumu ekleyin
- Yedekleme gibi kritik görevlerin loglarını düzenli kontrol edin
Bu kurallar cron ile ilgili karşılaşılan sorunların büyük kısmını daha baştan önler. Kalan kısım deneyimle gelir; farklı betik dillerinin cron ortamında nasıl davrandığı, birkaç gerçek görev yazıldıktan sonra netleşir.
Veritabanı yedekleme de cron ile sık otomatikleştirilen bir başka görevdir. MySQL için basit bir dump betiği şöyle çalışır:
0 1 * * * /usr/bin/mysqldump -u yedek_kullanici -p'sifre' veritabani > /backup/db-$(date +%F).sql
Bu satırda $(date +%F) ifadesi her yedeğin dosya adına o günün tarihini ekler; böylece her gün ayrı bir dosya oluşur ve eski yedekler üzerine yazılmaz. Şifreyi doğrudan crontab satırına yazmak yerine bir .my.cnf yapılandırma dosyasında saklamak güvenlik açısından daha doğrudur.
Disk kullanımını izleyen ve belirli bir eşik aşıldığında uyarı gönderen bir cron job da yaygın bir örnektir:
0 */6 * * * /home/kullanici/scripts/disk-kontrol.sh
Bu betik altı saatte bir çalışıp disk doluluğunu kontrol eder ve eşik aşıldığında bir bildirim gönderir. Küçük ama sürekli çalışan bu tür kontroller, büyük sorunlar hâline gelmeden önce erken uyarı sağlar.
Henüz yorum yok.
Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.