Sisteminizde her gece otomatik olarak yedek alınıyor, log dosyaları temizleniyor, raporlar oluşturuluyor. Peki bunları kim yapıyor? Cevap basit: cron. Unix/Linux dünyasının en eski ve en güvenilir otomasyon araçlarından biri olan cron, sistem yöneticilerinin vazgeçilmez silahıdır. Bir kez doğru kurduğunuzda arka planda sessiz sedasız çalışır, sizi uykuda bile korur.
Cron Job Nedir?
Cron, Unix tabanlı işletim sistemlerinde belirli zamanlarda veya belirli aralıklarla komut veya script çalıştırmak için kullanılan bir zamanlama servisidir. Adını Yunanca “chronos” (zaman) kelimesinden alır. Cron job ise bu servis aracılığıyla zamanlanmış her bir göreve verilen isimdir.
Sistem açıldığında arka planda crond adında bir daemon (arka plan servisi) çalışmaya başlar. Bu daemon, her dakika uyanır, tanımlanmış zamanlamaları kontrol eder ve vakti gelen işleri çalıştırır. İşte bu kadar basit. Ama bu basitliğin arkasında inanılmaz derecede güçlü bir esneklik yatıyor.
Cron’u şöyle düşünebilirsiniz: Evinizin alarm saati değil, akıllı ev sistemi. Sadece sizi belirli saatte uyandırmakla kalmıyor, “her Pazartesi sabahı 6’da kahveyi yap, her Cuma akşamı 11’de çamaşır makinesini çalıştır” diyebiliyorsunuz.
Cron Servisi Durumunu Kontrol Etmek
Herhangi bir şey yapmadan önce cron servisinin çalıştığından emin olalım.
# systemd tabanlı sistemlerde (Ubuntu, CentOS 7+, Debian)
sudo systemctl status cron # Debian/Ubuntu
sudo systemctl status crond # CentOS/RHEL
# Çalışmıyorsa başlatmak için
sudo systemctl start cron
sudo systemctl enable cron # Sistem açılışında otomatik başlat
Cron paketinin kurulu olup olmadığını kontrol etmek için:
which cron
which crond
crontab --version
Crontab Dosyası Nedir?
Cron job’ları crontab (cron table) adı verilen dosyalarda saklanır. Her kullanıcının kendi crontab dosyası vardır ve bu dosyalar genellikle /var/spool/cron/ veya /var/spool/cron/crontabs/ dizininde bulunur. Bunların yanı sıra sistem genelinde geçerli crontab dosyaları da vardır.
Crontab yönetimi için kullanılan temel komutlar şunlardır:
crontab -e: Mevcut kullanıcının crontab dosyasını düzenlercrontab -l: Mevcut kullanıcının crontab içeriğini listelercrontab -r: Mevcut kullanıcının crontab dosyasını siler (dikkatli olun!)crontab -u kullanici -e: Belirtilen kullanıcının crontab dosyasını düzenler (root yetkisi gerekir)
crontab -e komutunu ilk çalıştırdığınızda hangi editörü kullanmak istediğinizi soracaktır. Nano yeni başlayanlar için daha kolaydır, vim tercih edenler için ise klasik seçimdir.
Cron Syntax: Beş Alan Kuralı
İşte cron’un kalbi. Her cron job satırı aşağıdaki formatı takip eder:
* * * * * çalıştırılacak_komut
│ │ │ │ │
│ │ │ │ └── Haftanın günü (0-7, 0 ve 7 = Pazar)
│ │ │ └──── Ay (1-12)
│ │ └────── Ayın günü (1-31)
│ └──────── Saat (0-23)
└────────── Dakika (0-59)
Her alanda kullanabileceğiniz özel karakterler:
(yıldız): “Her” anlamına gelir. Dakika alanındayazarsanız “her dakika” demektir.,(virgül): Birden fazla değer belirtmek için.1,15,30gibi.-(kısa çizgi): Aralık belirtmek için.9-17gibi, 9’dan 17’ye kadar./(eğik çizgi): Adım değeri belirtmek için.*/5her 5 birimde bir anlamına gelir.
Temel Örneklerle Syntax Pratiği
Teoriden pratiğe geçelim. En çok kullanılan senaryoları inceleyelim:
# Her dakika çalıştır
* * * * * /path/to/script.sh
# Her saat başı çalıştır (her saatin 0. dakikası)
0 * * * * /path/to/script.sh
# Her gün sabah 3'te çalıştır
0 3 * * * /path/to/script.sh
# Her Pazartesi sabah 9'da çalıştır
0 9 * * 1 /path/to/script.sh
# Her ayın 1'inde gece yarısı çalıştır
0 0 1 * * /path/to/script.sh
# Her 15 dakikada bir çalıştır
*/15 * * * * /path/to/script.sh
# Hafta içi (Pazartesi-Cuma) her saat başı çalıştır
0 * * * 1-5 /path/to/script.sh
# Her yılın 1 Ocak'ında çalıştır
0 0 1 1 * /path/to/script.sh
Özel Cron Ifadeleri
Cron, bazı yaygın zamanlamalar için kısayol ifadeler de sunar. Bunları kullanmak hem yazımı kolaylaştırır hem de okunabilirliği artırır:
@reboot: Sistem her açıldığında bir kez çalıştır@hourly: Her saat başı çalıştır (0ile aynı)@dailyveya@midnight: Her gün gece yarısı çalıştır (0 0 *ile aynı)@weekly: Her hafta Pazar gece yarısı çalıştır (0 0 0ile aynı)@monthly: Her ayın ilk günü gece yarısı çalıştır (0 0 1ile aynı)@yearlyveya@annually: Her yılın ilk günü çalıştır (0 0 1 1 *ile aynı)
# Sistem açıldığında bir scripti çalıştır
@reboot /home/ubuntu/scripts/startup.sh
# Her gün gece yarısı log temizliği yap
@daily /usr/local/bin/clean_logs.sh
# Her hafta yedek al
@weekly /usr/local/bin/weekly_backup.sh
Gerçek Dünya Senaryoları
Senaryo 1: Otomatik Yedekleme
Bir web sunucusunda MySQL veritabanını her gece yedekleyelim:
# /usr/local/bin/db_backup.sh içeriği
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/mysql"
DB_NAME="production_db"
DB_USER="backup_user"
DB_PASS="guclu_sifre"
mkdir -p $BACKUP_DIR
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz
# 30 günden eski yedekleri sil
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
echo "Yedekleme tamamlandı: ${DB_NAME}_${DATE}.sql.gz"
Bu scripti crontab’a ekleyelim:
# Her gün sabah 2:30'da veritabanı yedeği al
30 2 * * * /usr/local/bin/db_backup.sh >> /var/log/db_backup.log 2>&1
Senaryo 2: Log Rotasyonu ve Temizliği
# Her Pazar sabah 4'te 90 günden eski log dosyalarını temizle
0 4 * * 0 find /var/log/uygulama -name "*.log" -mtime +90 -exec gzip {} ;
# Her gün gece 1'de access log'larını arşivle
0 1 * * * /usr/local/bin/archive_logs.sh
# Her ayın ilk günü eski arşivleri S3'e yükle
0 3 1 * * aws s3 sync /var/log/arsiv/ s3://sirket-loglar/$(date +%Y%m)/
Senaryo 3: Sistem Sağlık Kontrolleri
# Her 5 dakikada bir disk kullanımını kontrol et, %90 üstündeyse uyarı gönder
*/5 * * * * /usr/local/bin/disk_check.sh
# Her saat başı çalışan process sayısını logla
0 * * * * ps aux | wc -l >> /var/log/process_count.log
# Hafta içi her sabah 8'de servis durumlarını kontrol et ve rapor gönder
0 8 * * 1-5 /usr/local/bin/service_health_check.sh | mail -s "Günlük Servis Raporu" [email protected]
Cron’da Çıktı Yönetimi
Cron job’ları varsayılan olarak çıktıları e-posta olarak gönderer. Ancak çoğu ortamda mail sunucusu yapılandırılmamış olduğundan bu çıktılar kaybolur veya hata verir. Çıktıları doğru yönetmek kritik önem taşır.
# Tüm çıktıyı yoksay (ne stdout ne stderr loglanmaz)
* * * * * /path/to/script.sh > /dev/null 2>&1
# Sadece stdout'u logla, stderr'i yoksay
* * * * * /path/to/script.sh >> /var/log/myscript.log 2>/dev/null
# Hem stdout hem stderr'i aynı dosyaya logla
* * * * * /path/to/script.sh >> /var/log/myscript.log 2>&1
# Zaman damgasıyla birlikte logla
* * * * * echo "$(date '+%Y-%m-%d %H:%M:%S') - $(script.sh)" >> /var/log/myscript.log 2>&1
Önemli bir ipucu: Log dosyalarınız büyüyebilir. Kritik job’larınız için logrotate yapılandırması yapmayı unutmayın.
Ortam Değişkenleri ve PATH Sorunu
Cron job’larında en sık karşılaşılan sorun, komutun terminalde çalışmasına rağmen cron’da çalışmamasıdır. Bunun temel sebebi, cron’un farklı bir ortamda çalışmasıdır. Cron’un PATH değişkeni çok kısıtlıdır.
# Cron'un varsayılan PATH'i görmek için
* * * * * env > /tmp/cron_env.txt
Bu dosyayı incelediğinizde PATH’in ne kadar kısıtlı olduğunu göreceksiniz. Çözüm yolları:
# Crontab'ın başına PATH tanımla
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Her işte tam yol kullan
0 2 * * * /usr/bin/python3 /home/user/scripts/rapor.py
# Script içinde PATH'i tanımla (önerilen yöntem)
#!/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# ... geri kalanı
Crontab dosyasında ortam değişkeni tanımlamanın tüm yapısı:
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
# İşler buraya
0 2 * * * /usr/local/bin/yedek_al.sh >> /var/log/yedek.log 2>&1
Sistem Genelinde Cron Dosyaları
/etc/cron.d/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ dizinlerini de mutlaka bilmeniz gerekir. Sistem servisleri genellikle kendi cron job’larını buraya yerleştirir.
# /etc/cron.d/ içine yerleştirilen dosyalar farklı formattadır
# Kullanıcı adı da belirtmek gerekir
# DK SAAT GÜN AY HGÜN KULLANICI KOMUT
# /etc/cron.d/uygulama_yedek örneği
30 2 * * * root /usr/local/bin/uygulama_yedek.sh >> /var/log/yedek.log 2>&1
# /etc/cron.daily/ içine sadece çalıştırılabilir script koymanız yeterli
# Bu dizine koyduğunuz scriptler her gün otomatik çalışır
ls -la /etc/cron.daily/
/etc/crontab dosyası da sistem genelinde geçerlidir ve benzer şekilde kullanıcı adı alanı içerir:
# /etc/crontab örneği
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
Cron Job Debugging
Job’unuz neden çalışmıyor? İşte sistematik debug adımları:
1. Script’i Manuel Çalıştırın
Önce script’i doğrudan terminalde çalıştırın. Hata alıyorsanız cron’a taşımadan önce düzeltin.
2. Cron Log’larını İnceleyin
# Ubuntu/Debian
grep CRON /var/log/syslog
tail -f /var/log/syslog | grep CRON
# CentOS/RHEL
tail -f /var/log/cron
# Tüm sistemlerde journalctl ile
journalctl -u cron -f
journalctl -u crond -f
3. Script İzinlerini Kontrol Edin
# Script çalıştırılabilir olmalı
chmod +x /usr/local/bin/script.sh
# Doğru kullanıcıya ait olmalı
ls -la /usr/local/bin/script.sh
4. Cron Ortamını Simüle Edin
# Cron'un çalıştıracağı kullanıcı ile, kısıtlı ortamda test et
sudo -u kullanici env -i HOME=/home/kullanici SHELL=/bin/bash PATH=/usr/bin:/bin /usr/local/bin/script.sh
Güvenlik Konuları
Cron kullanırken güvenliği asla ihmal etmeyin.
/etc/cron.allow: Sadece bu dosyada listelenen kullanıcılar crontab kullanabilir. Bu dosya varsa, listede olmayan kimse crontab kullanamaz./etc/cron.deny: Bu dosyada listelenen kullanıcılar crontab kullanamaz.- Cron job’larında asla düz metin parola yazmayın. Bunun yerine environment file veya vault çözümleri kullanın.
- Root crontab’ına dikkat edin. Mümkün olduğunca minimum yetkiyle çalışan kullanıcılar kullanın.
- Script dosyalarını world-writable yapmayın.
# Sadece belirli kullanıcıların cron kullanmasına izin ver
echo "deploy" >> /etc/cron.allow
echo "backup_user" >> /etc/cron.allow
# Belirli kullanıcıları cron'dan yasakla
echo "www-data" >> /etc/cron.deny
Crontab Syntax Doğrulama Araçları
Yazdığınız cron expression’ın doğru olduğundan emin olmak için araçlar kullanabilirsiniz:
# crontab guru online aracına benzer şekilde
# Komut satırında test için systemd-analyze kullanabilirsiniz
systemd-analyze calendar "Mon *-*-* 09:00:00"
# Basit bir doğrulama için run-cron gibi araçlar
# pip ile kurabilirsiniz
pip install croniter
python3 -c "
from croniter import croniter
from datetime import datetime
cron = croniter('*/15 9-17 * * 1-5', datetime.now())
for i in range(5):
print(cron.get_next(datetime))
"
Bu Python örneği size bir sonraki 5 çalışma zamanını verecektir. Karmaşık cron expression’ları doğrulamak için harika bir yöntemdir.
Cron Alternatifleri: Ne Zaman Başka Bir Şey Kullanmalısınız?
Cron mükemmel bir araç ama her derde deva değil. Şu durumlarda alternatiflere bakın:
- Anacron: Sürekli açık olmayan sunucular için. Sistem kapalıyken kaçırılan job’ları çalıştırır.
- Systemd Timer: Modern Linux sistemlerinde cron’a güçlü bir alternatif. Bağımlılık yönetimi, daha iyi logging ve servis entegrasyonu sunar.
- Celery Beat: Python uygulamaları için distributed task scheduling.
- Jenkins: CI/CD pipeline’ları ve karmaşık iş akışları için.
Basit sistem görevleri için cron hala en pratik ve yaygın çözümdür. Yeni bir şey öğrenmek zorunda kalmadan işi halleder.
Sonuç
Cron, onlarca yıldır sistem yöneticilerinin güvendiği, sade ama güçlü bir araçtır. Syntax’ı ilk bakışta korkutucu görünse de beş alan kuralını bir kez sindirdiğinizde gerisi kolaylaşır. Dakika, saat, ayın günü, ay, haftanın günü. Bu sırayı ezberlediğinizde cron expression yazmak neredeyse otomatik hale gelir.
Gerçek dünyada dikkat etmeniz gereken en önemli noktalar şunlardır: her zaman tam yollar kullanın, çıktıları mutlaka yönetin, job’larınızı log alacak şekilde yapılandırın ve cron log’larını düzenli takip edin. Özellikle 2>&1 yönlendirmesini unutmamanızı öneririm; sessizce başarısız olan cron job’ları en sinir bozucu sysadmin deneyimlerinden biridir.
Son olarak şunu söyleyeyim: cron’u bir kez düzgün öğrendiğinizde, tekrarlayan manüel işlerin büyük çoğunluğundan kurtulacaksınız. Sistem yönetiminde gerçek otomasyon burada başlar.