macOS Unix tabanlıdır; bu yüzden klasik cron job hâlâ çalışır. Apple ise zamanlanmış işler için launchd'yi tercih eder: her iş ayrı bir plist dosyasıdır, kaçırılan takvim işleri uyanınca çalışabilir ve saniye hassasiyeti mümkündür. Bu rehber her iki yöntemi, izinleri ve gerçek hata mesajlarını kapsar.
Beş alanlı ifade yazmak için crontab sözdizimi yeterlidir. Linux sunucu karşılaştırması için Linux cron job, Windows tarafı için Windows görev zamanlayıcı rehberlerine bakın. Resmi Apple arşiv belgesi launchd'yi önerir; cron desteklenir ama önerilmez. Kavrama yeni başlıyorsanız zamanlanmış görev nedir rehberi cron'un çalışma modelini baştan anlatır.
Mac dizüstü bilgisayarlarda uyku kritik farktır. Görev saatinde Mac uykudaysa cron o anı atlar; launchd'de StartCalendarInterval ile tanımlı iş, uyanınca bir kez telafi edilebilir. Mac tamamen kapalıysa her iki sistem de bir sonraki plana kalır.
macOS'ta Cron Kullanımı
Geliştirici makinesinde hızlı dakikalık işler için crontab hâlâ pratiktir. Önce izinleri, sonra sözdizimini ayarlayın.
Full Disk Access (Catalina ve sonrası)
Korumalı klasörlere (Masaüstü, Belgeler, İndirilenler vb.) arka plan erişimi TCC ile kısıtlıdır. Cron dosya taşıyamıyorsa izin eksik demektir.
- System Settings (eski adıyla System Preferences) → Privacy & Security → Full Disk Access.
+ile/usr/sbin/cronekleyin (Git ile yol yazmak için Cmd+Shift+G).- Script Masaüstü/Belgeler okuyorsa script dosyasının kendisini de ekleyin; yalnızca
/bin/basheklemek çoğu zaman yetmez. - Terminal'e de Full Disk Access vermeniz,
crontab -eve test çalıştırmaları için faydalıdır.
Crontab oluşturma
crontab -e
crontab -l
Örnek satırlar (Apple Silicon'da Homebrew genelde /opt/homebrew):
# Her gün 09:00 — PDF arşivle
0 9 * * * /bin/mv /Users/kullanici/Desktop/*.pdf /Users/kullanici/Documents/PDF-Arsiv/ 2>/dev/null
# Her saat Homebrew güncellemesi kontrolü
0 * * * * /opt/homebrew/bin/brew update >/dev/null 2>&1
# Her gece Time Machine tetikle
0 0 * * * /usr/bin/tmutil startbackup --auto >/dev/null 2>&1
brew, node, php için mutlak yol yazın.Launchd ile Zamanlanmış Görevler
Launchd, macOS'un birincil süreç ve zamanlama sistemidir. Yapılandırma XML plist dosyasıdır. Apple belgesine göre kaçırılan StartCalendarInterval işi uyanınca çalışabilir.
Plist konumları
~/Library/LaunchAgents/ → Kullanıcı (oturum açınca)
/Library/LaunchAgents/ → Tüm kullanıcılar
/Library/LaunchDaemons/ → Sistem / root
/System/Library/LaunchDaemons/ → Apple (dokunmayın)
Örnek LaunchAgent plist
Dosyayı ~/Library/LaunchAgents/com.kullanici.gunluk-yedek.plist olarak kaydedin:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.kullanici.gunluk-yedek</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/kullanici/scripts/yedek.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>/Users/kullanici/logs/yedek-out.log</string>
<key>StandardErrorPath</key>
<string>/Users/kullanici/logs/yedek-err.log</string>
<key>RunAtLoad</key>
<false/>
</dict>
</plist>
Yükleme ve yönetim
- Log dizinini oluşturun:
mkdir -p ~/logs - Plist sözdizimini doğrulayın:
plutil -lint ~/Library/LaunchAgents/com.kullanici.gunluk-yedek.plist - Yükleyin (Ventura+ için bootstrap tercih edin).
launchctl list | grep gunluk-yedekile durumu kontrol edin.
# Klasik (eski macOS)
launchctl load ~/Library/LaunchAgents/com.kullanici.gunluk-yedek.plist
launchctl unload ~/Library/LaunchAgents/com.kullanici.gunluk-yedek.plist
# Ventura ve sonrası
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.kullanici.gunluk-yedek.plist
launchctl bootout gui/$(id -u)/com.kullanici.gunluk-yedek
# Manuel bir kez çalıştır
launchctl start com.kullanici.gunluk-yedek
# veya: launchctl kickstart -k gui/$(id -u)/com.kullanici.gunluk-yedek
Zamanlama anahtarları
Takvim (StartCalendarInterval) — eksik anahtar joker kabul edilir:
<key>StartCalendarInterval</key>
<dict>
<key>Weekday</key><integer>1</integer>
<key>Hour</key><integer>9</integer>
<key>Minute</key><integer>0</integer>
</dict>
Aralık (StartInterval) — saniye cinsinden:
<key>StartInterval</key>
<integer>900</integer>
Birden fazla saat için StartCalendarInterval bir dizi (array) olabilir.
Gerçek Senaryolar
Senaryo 1: Her 15 dakikada proje yedeği (launchd)
StartInterval değerini 900 saniye yapın. Script içinde kaynak ve hedef için mutlak yol kullanın; göreli path LaunchAgent ortamında kırılır. Çıktıyı mutlaka StandardOutPath ve StandardErrorPath ile dosyaya yazın — aksi halde sessiz başarısızlıkları fark edemezsiniz. İlk kurulumda RunAtLoad geçici olarak true yapıp agent'ı yükleyerek bir kez tetikleyebilir, sonra false'a çekebilirsiniz.
Yedek klasörü iCloud veya Masaüstü altındaysa Full Disk Access şarttır. Mümkünse yedek hedefini ~/Backups gibi TCC koruması daha az olan bir dizine alın.
Senaryo 2: Hafta içi 09:00 rapor (cron)
0 9 * * 1-5 /usr/bin/python3 /Users/kullanici/scripts/rapor.py >> /Users/kullanici/logs/rapor.log 2>&1
Python yolu için which python3 kullanın; Homebrew Python ise /opt/homebrew/bin/python3 yazın. Rapor e-posta veya API çağırıyorsa ağın hazır olduğundan emin olun; Mac henüz uyanıyorsa kısa bir sleep 30 veya launchd tercih edin. Log dosyasını haftalık kontrol etmek, “cron hiç çalışmadı” sanılan birçok vakayı çözer: satır yoksa zamanlama veya izin, satır var ama hata varsa script tarafı sorunludur.
İş bitmiyorsa cron job çalışmıyor kontrol listesindeki ortam ve PATH maddelerini Mac'e uyarlayın.
Cron vs Launchd
| Özellik | Cron | Launchd |
|---|---|---|
| Yapılandırma | Tek satır | XML plist |
| Minimum birim | Dakika | Saniye |
| Kaçırılan takvim işi | Atlanır | Uyanınca çalışabilir |
| Dosya izleme | Yok | WatchPaths |
| Apple önerisi | Hayır | Evet |
Sık Hatalar ve Çözümleri
1. Operation not permitted
Neden: TCC / Full Disk Access eksik.
Çözüm: Privacy & Security → Full Disk Access altına /usr/sbin/cron veya script yolunu ekleyin; agent'ı unload/load (veya bootout/bootstrap) edin.
2. Load failed: 5: Input/output error veya benzer launchctl hatası
Neden: Bozuk plist, yinelenen Label, yanlış sahiplik.
Çözüm: plutil -lint dosya.plist; Label'ın benzersiz olduğundan emin olun; Ventura+'da bootstrap kullanın.
3. /bin/sh: brew: command not found
Neden: Cron PATH'inde Homebrew yok.
Çözüm: /opt/homebrew/bin/brew (Apple Silicon) veya /usr/local/bin/brew (Intel) yazın.
4. Görev “yüklü” ama log boş
Neden: Script exit 0 üretiyor ama iş yapmıyor; veya stdout yönlendirilmemiş; veya Mac o saatte uykudaydı.
Çözüm: StandardOutPath/StandardErrorPath ekleyin; script'i Terminal'de elle çalıştırın; uyku için launchd tercih edin.
5. crontab: tmp file must be owned by you
Neden: Geçici dosya sahipliği veya izin sorunu.
Çözüm: Normal kullanıcı olarak crontab -e çalıştırın; sudo ile kullanıcı crontab'ını karıştırmayın (sudo crontab -e root'un tablosudur).
cronjob.com.tr ile HTTP Tabanlı Alternatif
Mac kapalı veya uykudayken yerel cron/launchd çalışmaz. İşiniz genel internetteki bir HTTPS uç noktasıysa (ör. sunucudaki bakım URL'si) cronjob.com.tr Mac açık olmasa da tetikler. Ücretsizdir; kredi kartı istenmez. En kısa aralık 1 dakikadır.
<?php
declare(strict_types=1);
$beklenen = getenv('CRON_SECRET') ?: '';
$gelen = $_SERVER['HTTP_X_CRON_TOKEN'] ?? '';
if ($beklenen === '' || !hash_equals($beklenen, $gelen)) {
http_response_code(403);
exit('forbidden');
}
http_response_code(200);
echo 'ok';
Panelde URL, metot, X-Cron-Token ve zamanlamayı girin. Başarı HTTP 200–399; timeout aralığa göre (1 dk→55 sn, cron ifadeli→290 sn). TLS doğrulanır; localhost/özel IP'ye istek gitmez — uç nokta herkese açık olmalıdır.
Sıkça Sorulan Sorular (SSS)
Mac uyku modundayken cron çalışır mı?
Hayır. Uyku sırasında ne cron ne launchd çalışır. StartCalendarInterval ile tanımlı launchd işi, Mac uyanınca kaçırılan çalıştırmayı telafi edebilir; bilgisayar tamamen kapalıysa bir sonraki plana kadar bekler.
Hangisini kullanmalıyım: cron mu launchd mı?
Apple launchd'yi önerir. Basit dakikalık işlerde crontab pratik kalır; kaçırılan görevi yakalama, WatchPaths veya saniye aralığı istiyorsanız launchd kullanın.
launchctl load neden Load failed diyor?
Plist hatalı, Label çakışması veya dosya yolu yanlış olabilir. plutil -lint ile plist'i doğrulayın; macOS Ventura ve sonrasında load yerine bootstrap/bootout kullanın.
Full Disk Access neden gerekli?
Catalina sonrası TCC, Masaüstü/Belgeler gibi korumalı klasörlere arka plan erişimini kısıtlar. cron veya script'inize Privacy & Security altında Full Disk Access verin; aksi halde Operation not permitted görürsünüz.
Homebrew yolları cron'da neden bulunmaz?
Cron minimal PATH kullanır. /opt/homebrew/bin/brew veya /usr/local/bin/brew gibi mutlak yol yazın; PATH'e güvenmeyin.
Sonuç
Mac'te hızlı denemeler için crontab, kalıcı ve uykuya dayanıklı işler için launchd uygundur. İzinleri verin, mutlak yol kullanın, log yazın. Makine kapalıyken tetiklenmesi gereken sunucu işlerini cronjob.com.tr ile HTTP üzerinden planlayın.
Hemen Ücretsiz Cron Job Oluşturun
Mac uykudayken veya kapalıyken sunucunuzdaki bakım uç noktası tetiklensin: cronjob.com.tr'de URL, X-Cron-Token başlığı ve dakikalık zamanlamayı tanımlayın; uç nokta erişilemez olduğunda ardışık hata eşiği e-posta uyarısı gönderir. Kayıt ücretsizdir, kredi kartı istenmez.
Ücretsiz Başla →