Cron Job Nasıl Oluşturulur? Crontab Söz Dizimi ve Örnekler

Cron job nedir ve nasıl oluşturulur?
Cron job, Linux ve Unix benzeri sistemlerde cron servisinin belirlediğiniz dakika, saat, gün, ay ve haftanın günü kombinasyonunda kendiliğinden çalıştırdığı planlı görevdir. Bir cron job oluşturmak için terminalde crontab -e komutunu açar, beş zaman alanı ile komutun tam yolunu içeren tek satırı ekler ve dosyayı kaydedersiniz.
Gece yedeği almak, her sabah rapor üretmek, önbelleği temizlemek ya da WordPress'in planlı işlerini düzenli tetiklemek gibi tekrar eden işler cron sayesinde elle uğraşmadan yürür. Örneğin bir e-ticaret sitesinde stok senkronu, sepet hatırlatma e-postası ve site haritası üretimi çoğu zaman bir cron görevine bağlıdır. Dolayısıyla cron'u doğru kurmak, sitenin "kendi kendine" yaptığını sandığınız pek çok işin gerçekten yapılıp yapılmadığını belirler.
Bu rehberde söz dizimini, crontab komutlarını, ortam değişkenlerinden kaynaklı hataları, cPanel arayüzünü, WordPress'teki wp-cron ayarını ve çakışmayı önleyen flock kullanımını anlatıyoruz. Biz dijital pazarlama ve web ekibiyiz, hosting firması değiliz; bu yüzden anlatımı crontab(5) kılavuz sayfası gibi resmi belgelere dayandırıyoruz. Kendi dağıtımınızdaki man 5 crontab çıktısı ise her zaman son sözü söyler; çünkü cron uygulamaları arasında küçük farklar var.
Cron arka planda nasıl çalışır, crontab dosyası neyi tutar?
Cron, sistem açıldığında başlayan ve sürekli arka planda bekleyen bir servistir. Servis her dakika zamanlama tablolarını kontrol eder ve o dakikaya uyan satırları çalıştırır. Bu tabloların adı crontab, yani "cron table" kısaltmasıdır.
Her kullanıcının kendine ait bir crontab'ı olabilir. Ayrıca sistem genelinde /etc/crontab dosyası ve /etc/cron.d/ klasöründeki dosyalar da işin içine girer. Kullanıcı crontab'ını doğrudan bir metin dosyası gibi açmazsınız; bunun yerine crontab komutunu kullanırsınız. Bu komut dosyayı düzenledikten sonra söz dizimini kontrol eder ve servise yeni tabloyu bildirir.
Crontab içindeki her etkin satır iki türden biridir: ya bir ortam değişkeni ataması ya da bir planlı komut. Diyez (#) ile başlayan satırlar yorumdur ve cron bunları atlar; bu sayede her göreve açıklama yazabilirsiniz. Kılavuz sayfası önemli bir ayrıntıyı da vurgular: cron, her satırın yeni satır karakteriyle bitmesini ister. Son satırdan sonra Enter'a basmazsanız o görev hiç çalışmayabilir.
Kısacası cron'un mantığı basittir: servis saati izler, tablo neyin ne zaman çalışacağını söyler. Sorunların neredeyse tamamı tablonun yazımından ya da komutun cron ortamında farklı davranmasından doğar.
Crontab söz dizimini nasıl okursunuz?
Bir kullanıcı crontab satırı beş zaman alanı ve ardından gelen komuttan oluşur. Alanları soldan sağa şu sırayla okursunuz:
- Dakika: 0 ile 59 arası.
- Saat: 0 ile 23 arası.
- Ayın günü: 1 ile 31 arası.
- Ay: 1 ile 12 arası ya da İngilizce ay adının ilk üç harfi (jan, feb gibi).
- Haftanın günü: 0 ile 7 arası; 0 ve 7 pazar günüdür, isterseniz mon, tue gibi kısaltmalar kullanırsınız.
# dakika saat ayin-gunu ay haftanin-gunu komut30 3 * * * /usr/local/bin/gece-yedegi.shYukarıdaki satır her gün saat 03.30'da betiği çalıştırır. Yıldız işareti "bu alanın tüm değerleri" anlamına gelir; dolayısıyla ayın günü, ay ve haftanın günü kısıtsız kalır.
Kılavuzdaki ince bir kural sık yanıltır: ayın günü ve haftanın günü alanlarının ikisini birden kısıtlarsanız cron, ikisinden biri tuttuğunda görevi çalıştırır. Örneğin 0 9 13 * 5 "13'ü cumaya denk gelirse" anlamına gelmez; her ayın 13'ünde ve her cuma saat 09.00'da çalışır. Böyle bir koşul gerekiyorsa tarihi betiğin içinde kontrol etmeniz daha güvenlidir.
Yıldız, virgül, tire ve eğik çizgi ne anlama gelir?
Zaman alanlarında dört özel karakter işinizi kolaylaştırır. Bunları birleştirerek tek satırda oldukça esnek zamanlamalar kurarsınız.
- Yıldız (*): Alanın ilk değerinden son değerine kadar her şey. Saat alanındaki yıldız "her saat" demektir.
- Virgül (,): Liste oluşturur.
0 8,12,18 * * *günde üç kez, 08.00, 12.00 ve 18.00'de çalışır. - Tire (-): Aralık belirtir ve uçlar dahildir.
0 9-17 * * 1-5hafta içi mesai saatlerinde her saat başı çalışır. - Eğik çizgi (/): Bir aralık içinde adım tanımlar.
*/15 * * * *her 15 dakikada bir,0-30/10ise 0, 10, 20 ve 30. dakikalarda çalışır.
Adım ifadesini yorumlarken dikkatli olun. */7 dakika alanında "her yedi dakikada bir" gibi durur; ancak sayım her saat 0'dan yeniden başladığı için saatin sonunda 56'dan sonraki aralık kısa kalır. Bu yüzden 60'ı tam bölen adımlar (5, 10, 15, 20, 30) daha öngörülebilir sonuç verir.
Ayrıca bazı cron uygulamaları ek söz dizimi destekler. Örneğin cronie tabanlı dağıtımların kılavuzu, tilde (~) ile bir aralıkta rastgele değer seçmeyi anlatır. Bu tür eklentiler her sistemde yoktur; taşınabilir bir satır istiyorsanız yalnız yukarıdaki dört karakterle yetinin.
@reboot, @daily ve diğer kısayollar ne işe yarar?
Beş alanı her seferinde yazmak yerine kılavuzda tanımlı kısa adları kullanabilirsiniz. Kısayollar okunabilirliği artırır ve özellikle ekip içinde paylaşılan tablolarda yanlış anlamayı azaltır.
@reboot: Sistem yeniden başladıktan sonra bir kez çalışır.@yearlyve@annually: Yılda bir kez,0 0 1 1 *ile aynı.@monthly: Ayda bir kez,0 0 1 * *ile aynı.@weekly: Haftada bir kez,0 0 * * 0ile aynı.@daily: Günde bir kez,0 0 * * *ile aynı.@hourly: Saatte bir kez,0 * * * *ile aynı.
Burada dikkat etmeniz gereken nokta şu: @daily gece yarısını kastediyor. Sunucuda birçok görev aynı anda gece yarısına yığılırsa disk ve veritabanı aynı dakikada yük alır. Bu nedenle ağır işleri 17 2 * * * gibi "yuvarlak olmayan" dakikalara dağıtmanızı öneririz.
@reboot ise kullanışlı ama sınırlı bir araçtır. Sunucu açılırken ağ, veritabanı ya da bağlı diskler henüz hazır olmayabilir. Kalıcı çalışması gereken bir uygulama için cron yerine systemd servisi daha uygundur; bu yaklaşımı Node.js uygulamasını systemd ile yayına alma rehberimizde adım adım anlattık.
Cron job adım adım nasıl oluşturulur?
SSH erişiminiz olan bir VPS ya da sunucuda ilk cron job'unuzu kurmak birkaç dakika sürer. Henüz sunucunun temel kurulumunu yapmadıysanız önce Ubuntu Server ilk yapılandırma adımlarına göz atın. Ardından şu sırayı izleyin:
- Görevi önce elle çalıştırın. Komut terminalde hatasız bitmiyorsa cron'da da bitmez.
- Komuttaki her programın tam yolunu bulun:
command -v phpya dawhich phpçıktısını not edin. crontab -eile kendi tablonuzu açın. İlk açılışta bazı sistemler hangi editörü kullanmak istediğinizi sorar.- Üstüne bir yorum satırı, altına zamanlama satırını yazın ve çıktıyı bir log dosyasına yönlendirin.
- Dosyayı kaydedip çıkın. "installing new crontab" benzeri bir mesaj görürseniz tablo yüklenmiştir.
crontab -lile satırın yerinde durduğunu doğrulayın, ilk çalışmadan sonra log dosyasını kontrol edin.
# Her gece 02.17'de veritabanı yedeği17 2 * * * /usr/local/bin/db-yedek.sh >> /home/deploy/logs/db-yedek.log 2>&1İlk testte beklemek istemiyorsanız geçici olarak */2 * * * * yazıp iki dakika içinde log'a bakabilirsiniz. Test bitince zamanlamayı asıl değerine döndürmeyi unutmayın. Yedek görevlerinin hangi sıklıkta ve nereye alınacağını planlamak için web sitesi yedekleme stratejisi yazımız iyi bir başlangıç noktasıdır.
crontab -e, -l ve -r komutlarında nelere dikkat etmelisiniz?
crontab(1) kılavuzuna göre üç temel seçenek günlük işin neredeyse tamamını karşılar. Ancak bunlardan biri, dikkatsiz kullanıldığında bütün tabloyu tek hamlede siler.
| Komut | Ne yapar? | Risk ve ipucu |
|---|---|---|
crontab -e | Tabloyu VISUAL ya da EDITOR değişkenindeki editörle açar. | Kaydettiğinizde komut söz dizimini kontrol eder ve hata varsa yeniden düzenlemeyi teklif eder. |
crontab -l | Mevcut tabloyu ekrana yazdırır. | Yedek almak için çıktıyı bir dosyaya yönlendirin. |
crontab -r | Mevcut tabloyu tamamen kaldırır. | Onay sormaz; -e ile tek harf farkı vardır. |
crontab -i -r | Silmeden önce y/Y onayı ister. | Destekleyen sistemlerde güvenli alışkanlık. |
crontab -u kullanici -l | Başka kullanıcının tablosunu gösterir. | Yalnız yetkili kullanıcı (root) kullanabilir. |
Klavyede "e" ile "r" yan yana durduğu için crontab -r kazasına sanıldığından sık rastlarız. Bu yüzden düzenlemeye başlamadan önce tablonun kopyasını almanızı öneririz:
crontab -l > ~/crontab-yedek-$(date +%F).txtBu satırı terminalde çalıştırırsınız, crontab içine yazmazsınız. Sebebini ilerideki "yüzde işareti" başlığında açıklıyoruz.
Kullanıcı crontab'ı ile sistem crontab'ı arasındaki fark nedir?
Cron görevlerini koyabileceğiniz birkaç yer var ve her birinin satır biçimi ile sahiplik mantığı farklıdır. Kılavuz sayfası, /etc/crontab ve /etc/cron.d/ içindeki görevleri "sistem görevi" sayar ve bu dosyalarda zaman alanlarından sonra bir kullanıcı adı alanı bekler.
| Konum | Kim düzenler? | Kullanıcı alanı | En uygun durum |
|---|---|---|---|
Kullanıcı crontab'ı (crontab -e) | Hesabın sahibi | Yok, görev o kullanıcıyla çalışır | Site sahibinin kendi betikleri, paylaşımlı hosting |
/etc/crontab | root | Var | Dağıtımın kendi bakım görevleri; elle eklemeyi sınırlı tutun |
/etc/cron.d/dosya | root ya da paket yöneticisi | Var | Bir uygulamaya ait görevleri ayrı dosyada toplamak |
| cPanel Cron Jobs | cPanel hesabı | Yok | SSH erişimi olmayan paylaşımlı hosting |
# /etc/cron.d/ornek-uygulama* * * * * www-data /usr/bin/php /var/www/example.com/artisan schedule:runKullanıcı alanını unutmak sistem dosyalarında en sık görülen hatadır; o zaman cron "www-data" yerine komutun ilk kelimesini kullanıcı adı sanır. Öte yandan aynı alanı kullanıcı crontab'ına yazarsanız bu kez kullanıcı adı komut gibi çalıştırılmaya çalışır. Kısacası satırı nereye koyduğunuzu her zaman kontrol edin.
Cron neden komutu bulamıyor, PATH sorununu nasıl çözersiniz?
"Terminalde çalışıyor ama cron'da çalışmıyor" şikâyetinin bir numaralı sebebi ortam farkıdır. Siz oturum açtığınızda kabuk; profil dosyalarını, PATH değişkenini, dil ayarlarını ve sürüm yöneticilerini yükler. Cron ise bunların çoğunu yüklemez.
Kılavuza göre cron, SHELL değişkenini /bin/sh olarak ayarlar; LOGNAME ve HOME değerlerini ise tablo sahibinin kullanıcı kaydından alır. PATH için dağıtıma göre değişen, oturumunuzdakinden çok daha kısa bir varsayılan gelir. Dolayısıyla /usr/local/bin altındaki composer, wp ya da bir Node.js sürüm yöneticisinin kurduğu node cron içinde bulunamayabilir.
Çözüm için üç yol var:
- Tablonun en üstüne açık bir PATH satırı ekleyin.
- Bash'e özgü söz dizimi kullanan betiklerde
SHELL=/bin/bashtanımlayın. - En sağlamı: komut ve betik içindeki her programı tam yoluyla yazın.
SHELL=/bin/bashPATH=/usr/local/bin:/usr/bin:/binMAILTO=""*/10 * * * * /usr/local/bin/ornek-gorev.shCron'un gerçekte hangi ortamı gördüğünü merak ediyorsanız bir defalığına * * * * * env > /tmp/cron-ortam.txt satırını ekleyin, bir dakika sonra dosyayı okuyun ve satırı silin. Böylece tahmin yerine somut veriyle çalışırsınız.
Mutlak yol kullanmak neden şart?
Cron görevi çalışırken geçerli dizin, sizin terminalde bulunduğunuz klasör değildir; genellikle kullanıcının ev dizinidir. Bu yüzden ./yedek.sh ya da php artisan gibi göreli ifadeler cron içinde ya hata verir ya da yanlış dosya üzerinde çalışır.
Kural basit: crontab satırında hem programın hem de dosyanın tam yolunu yazın. Betik içinde dosya okuyup yazıyorsanız, betiğin başında çalışma dizinine açıkça geçin ve geçiş başarısız olursa çıkın.
#!/bin/bashset -euo pipefailcd /var/www/example.com || exit 1/usr/bin/php artisan schedule:runBuradaki set -euo pipefail satırı, bir komut hata verdiğinde betiğin sessizce devam etmesini engeller. Örneğin veritabanı dökümü başarısız olduğu halde betik eski yedeği silip "tamam" yazarsa bunu ancak geri yükleme gününde fark edersiniz. Veritabanı dökümü ve geri yükleme ayrıntıları için mysqldump ve pg_dump rehberimize bakabilirsiniz.
PHP için de aynı titizlik gerekir. Paylaşımlı hostinglerde birden fazla PHP sürümü yer alır ve php komutu sitenizin kullandığı sürümü göstermeyebilir. Hangi sürümün etkin olduğunu cPanel PHP sürümü değiştirme rehberimizde anlatıyoruz; cron satırında da o sürümün tam yolunu kullanın.
Cron çıktısını log dosyasına nasıl yönlendirirsiniz?
Cron, bir görev ekrana çıktı ürettiğinde bunu varsayılan olarak tablo sahibine e-postayla gönderir; MAILTO değişkeni bu adresi belirler. Sunucuda e-posta altyapısı yoksa çıktı kaybolur, varsa gelen kutunuz yüzlerce gereksiz iletiyle dolar. Bu yüzden çıktıyı bilinçli olarak yönetmeniz gerekir.
>> /yol/gorev.log 2>&1: Hem normal çıktıyı hem hataları dosyanın sonuna ekler.> /dev/null 2>&1: Tüm çıktıyı atar. Yalnız sonucunu başka yerden izlediğiniz görevlerde kullanın.MAILTO="": O tablodaki görevler için e-posta gönderimini kapatır.
Satırın sonundaki 2>&1 sırası önemlidir: önce standart çıktıyı dosyaya, sonra hata akışını standart çıktıya yönlendirirsiniz. Sırayı ters yazarsanız hatalar yine kaybolur.
Log dosyaları da zamanla büyür. Uzun süre çalışan görevlerde dosyayı logrotate ile döndürmeyi ya da betiğin her satıra tarih yazmasını öneririz. Ayrıca cron servisinin kendi kayıtları vardır: Debian ve Ubuntu'da sistem günlüğünde "CRON" etiketiyle, systemd kullanan dağıtımlarda journalctl ile görürsünüz. Toplu log incelemesi için log analizi aracımızı da kullanabilirsiniz.
Yüzde işareti cron satırını neden bozar?
Crontab kılavuzundaki en az bilinen kurallardan biri yüzde işaretiyle ilgilidir. Komut kısmındaki kaçışsız bir % karakteri yeni satıra dönüşür; ilk yüzde işaretinden sonraki her şey komutun standart girdisine gider. Bu yüzden terminalde kusursuz çalışan date +%F içeren bir satır, cron içinde yarıda kalır.
# Hatalı: % işaretinden sonrası komuta girdi olur0 1 * * * /usr/bin/tar czf /yedek/site-$(date +%F).tgz /var/www/example.com# Doğru: yüzde işaretini ters eğik çizgiyle kaçırın0 1 * * * /usr/bin/tar czf /yedek/site-$(date +\%F).tgz /var/www/example.comDaha temiz bir yol ise tarih biçimlendirmesini tamamen betiğin içine taşımaktır. Böylece crontab satırı sade kalır, betik de terminalde ve cron'da aynı şekilde davranır. Bizim de tercih ettiğimiz düzen budur: crontab yalnız "ne zaman" sorusunu cevaplar, "nasıl" sorusu betiğe aittir.
Benzer bir tuzak tırnaklarda karşınıza çıkar. Cron satırı /bin/sh ile yorumlar; bu nedenle iç içe tırnak, değişken genişletme ve özel karakterler karmaşıklaştıkça hata ihtimali artar. Tek satıra sığmayan her mantığı ayrı bir betik dosyasına almanız hem okunabilirliği hem de hata ayıklamayı kolaylaştırır.
cPanel'de cron job nasıl eklenir?
Paylaşımlı hostingde çoğu zaman SSH erişiminiz olmaz; bu durumda cron job eklemek için cPanel'in arayüzünü kullanırsınız. cPanel belgelerine göre bu ekran "Advanced" (Gelişmiş) bölümünde, "Cron Jobs" adıyla yer alır.
- cPanel'e girip Gelişmiş bölümünden Cron Jobs ekranını açın.
- "Cron Email" alanına bildirim almak istediğiniz adresi yazın ya da bildirim istemiyorsanız alanı boş bırakın.
- "Common Settings" listesinden hazır bir sıklık seçin; liste dakika, saat, gün, ay ve hafta günü alanlarını otomatik doldurur.
- Command alanına komutun tam yolunu yazın ve görevi ekleyin.
- Mevcut görevleri aynı sayfanın altındaki listeden düzenleyin ya da silin.
cPanel belgeleri iki konuda açık uyarı yapar. Birincisi, bir görevin bitmesine yetecek aralık bırakmanızı ister; aksi halde sunucu önceki görev sürerken yenisini başlatabilir. İkincisi, cron içinde rm komutunu çok dikkatli kullanmanızı söyler, çünkü hatalı bir yol ev dizinindeki verileri silebilir.
Belirli bir görevin e-posta göndermesini istemiyorsanız komutun sonuna >/dev/null 2>&1 ekleyebilirsiniz. Komuttaki PHP yolu hosting sağlayıcısına göre değişir; sağlayıcınızın belgelerinde verdiği yolu kullanın. Ayrıca bazı sağlayıcılar çok sık çalışan görevleri kısıtlar; bu sınırı tahmin etmek yerine destek ekibine sorun.
WordPress wp-cron'u gerçek cron ile nasıl değiştirirsiniz?
WordPress'in ileri tarihli gönderiler, eklenti güncellemeleri ve e-posta kuyrukları için kullandığı WP-Cron gerçek bir cron değildir. WordPress geliştirici belgelerine göre WP-Cron her sayfa yüklemesinde devreye girer. Ziyaretçisi az olan bir sitede görevler gecikir; çok ziyaret alan sitede ise kontrol gereksiz yere sık tekrarlanır.
Çözüm, sayfa yüklemesine bağlı tetiklemeyi kapatıp işi sistemin zamanlayıcısına vermektir. Belgeler önce wp-config.php dosyasına şu satırı eklemenizi söyler:
define( 'DISABLE_WP_CRON', true );Ardından gerçek bir cron görevi tanımlarsınız. Resmi belge, wp-cron.php adresini HTTP üzerinden çağıran bir örnek verir ve 15 dakikalık aralığı */15 * * * * ile gösterir. Sunucuda WP-CLI kuruluysa, HTTP isteğine gerek kalmadan zamanı gelmiş olayları komut satırından çalıştırabilirsiniz:
*/15 * * * * cd /home/kullanici/public_html && /usr/local/bin/wp cron event run --due-now >> /home/kullanici/logs/wp-cron.log 2>&1Buradaki wp yolu sunucudan sunucuya değişir; command -v wp ile doğrulayın. Ayrıca DISABLE_WP_CRON satırını ekleyip cron görevini kurmayı unutursanız ileri tarihli yazılar yayımlanmaz, e-postalar gönderilmez. WordPress e-posta tarafında sorun yaşıyorsanız WP Mail SMTP kurulum rehberimiz de işinize yarar.
Cron job çalışmıyorsa nereden başlamalısınız?
Bir cron job beklendiği gibi çalışmadığında rastgele değişiklik yapmak yerine sabit bir teşhis sırası izlemek zaman kazandırır. Biz şu sırayı öneriyoruz:
- Servis ayakta mı?
systemctl status cronya da RHEL ailesindesystemctl status crondile kontrol edin. - Satır gerçekten tabloda mı?
crontab -lçıktısına bakın; doğru kullanıcının tablosunu incelediğinizden emin olun. - Cron görevi tetikledi mi? Sistem günlüğünde ilgili dakikada "CRON" kaydı arayın.
- Yol doğru mu? Programları ve dosyaları tam yolla yazdığınızı kontrol edin.
- İzin var mı? Betiğin çalıştırılabilir olduğunu (
chmod +x) ve görevi çalıştıran kullanıcının dosyalara erişebildiğini doğrulayın. - Satır sonu doğru mu? Windows'ta düzenlediğiniz betiklerde CRLF satır sonu "bad interpreter" hatasına yol açar; dosyayı LF biçimine çevirin. Crontab'ın son satırından sonra da boş bir yeni satır bırakın.
- Yüzde işareti var mı? Kaçışsız
%komutu böler. - Erişim yasağı var mı?
cron.allowdosyası varsa kullanıcınız orada yazmalı; yalnızcron.denyvarsa orada olmamalı.
Bu sırayı izlerken her adımda yalnız bir şeyi değiştirin. Aynı anda üç ayarı değiştirirseniz sorunun hangisiyle çözüldüğünü ya da hangisinin yeni hata getirdiğini anlayamazsınız.
Zaman dilimi farkı görevleri nasıl kaydırır?
"Görevi saat 09.00'a kurdum ama 06.00'da çalıştı" türünden bir sorun neredeyse her zaman zaman dilimiyle ilgilidir. Cron, sunucunun sistem saatine ve yerel zaman dilimine göre çalışır. Birçok bulut sunucusu UTC ile gelir; Türkiye ise UTC+3 kullanır. Dolayısıyla UTC sunucuda 0 9 * * * yazdığınız görev, Türkiye saatiyle 12.00'de çalışır.
Bu durumda iki seçeneğiniz var:
- Sunucunun zaman dilimini
timedatectl set-timezone Europe/Istanbulile değiştirip cron servisini yeniden başlatmak. - Sunucuyu UTC'de bırakıp zamanlamaları UTC'ye göre hesaplamak. Birden fazla ülkeye hizmet veren sistemlerde bu yaklaşım daha az sürpriz üretir.
Bazı cron uygulamaları, tablo bazında zaman dilimi belirlemek için CRON_TZ değişkenini destekler; kılavuz sayfası bunu tanımlar. Ancak bu değişkeni her dağıtım tanımaz, bu nedenle kullanmadan önce kendi sisteminizin man 5 crontab sayfasında arayın.
Saatin kendisinin kayması da ayrı bir risktir. Sistem saati birkaç dakika ileri ya da geri giderse görevler yanlış zamanda çalışır, loglardaki zaman damgaları birbirini tutmaz. Bunu önlemek için sunucuda zaman senkronizasyonunun açık olduğundan emin olun; ayrıntılar NTP ve Linux sunucuda zaman senkronizasyonu yazımızda.
flock ile çakışan görevleri nasıl önlersiniz?
Her beş dakikada bir çalışan bir görev bazen yedi dakika sürer. O zaman cron, önceki kopya bitmeden ikincisini başlatır; iki kopya aynı dosyalara ya da aynı tabloya yazdığında veri bozulabilir. cPanel belgelerinin uyardığı durum tam olarak budur.
Linux'ta util-linux paketiyle gelen flock bu sorunu kilit dosyasıyla çözer. flock(1) kılavuzuna göre -n seçeneği, kilit hemen alınamıyorsa beklemek yerine başarısız olmayı sağlar. Yani önceki kopya hâlâ çalışıyorsa yenisi hiç başlamaz.
*/5 * * * * /usr/bin/flock -n /tmp/stok-senkron.lock /usr/local/bin/stok-senkron.sh >> /home/deploy/logs/stok.log 2>&1Kılavuz iki seçeneği daha anlatır:
-w saniye: Kilidi belirtilen süre boyunca bekler, alamazsa vazgeçer.-E kod: Kilit alınamadığında dönecek çıkış kodunu belirler; varsayılan değer 1'dir. Kilit çakışmasını gerçek hatalardan ayırmak için işe yarar.
Kilit dosyasını her görev için ayrı adlandırın. Aynı kilidi iki farklı görev paylaşırsa biri diğerini gereksiz yere engeller. Ayrıca kilit, işlem bittiğinde ya da çöktüğünde çekirdek kilidi kendiliğinden bırakır; bu nedenle elle kilit dosyası silmeniz gerekmez.
Cron görevlerinde güvenlik için nelere dikkat etmelisiniz?
Cron, bir komutu sizin yokluğunuzda ve düzenli olarak çalıştırır. Bu güç yanlış ellerde kalıcılık aracına dönüşür; bu nedenle cron tabloları güvenlik denetiminde ilk bakılan yerlerden biridir.
- En az yetki: Görevi root yerine işi yapmaya yetecek kullanıcıyla çalıştırın. Bir web uygulamasının görevi, web uygulamasının kullanıcısıyla çalışmalı.
- Betik izinleri: Root'un çalıştırdığı bir betiği başka kullanıcılar düzenleyebiliyorsa, o kullanıcılar dolaylı olarak root yetkisi kazanır. Betiği ve bulunduğu klasörü yalnız sahibinin yazabileceği şekilde ayarlayın.
- Parolalar: Veritabanı parolasını crontab satırına yazmayın; çünkü süreç listesinde ve loglarda görünebilir. Yalnız sahibinin okuyabildiği bir yapılandırma dosyası kullanın.
- Erişim listeleri:
cron.allowvecron.denydosyalarıyla kimin crontab kullanabileceğini sınırlayın. - Düzenli denetim: Tanımadığınız bir cron satırı, özellikle dışarıdan dosya indirip çalıştıran bir satır görürseniz bunu ciddi bir uyarı işareti sayın.
Sunucuya erişimi daraltmak, cron'u korumanın da ilk adımıdır. SSH sertleştirmesi için swap ve SSH güvenliği rehberimize, kaba kuvvet girişimlerine karşı ise Fail2ban kurulum yazımıza bakabilirsiniz.
Sık kullanılan cron ifadeleri tablosu
Aşağıdaki tablo, web sitelerinde en çok ihtiyaç duyduğumuz zamanlamaları ve okunuşlarını bir arada verir. Değerleri kendi işinize göre uyarlayın; özellikle ağır görevleri yuvarlak olmayan dakikalara kaydırın.
| İfade | Anlamı | Örnek kullanım |
|---|---|---|
*/5 * * * * | Her 5 dakikada bir | Kuyruk işleme ve stok senkronu |
*/15 * * * * | Her 15 dakikada bir | WordPress planlı olayları |
0 * * * * | Her saat başı | Önbellek ısıtma, kur güncelleme |
17 2 * * * | Her gün 02.17 | Veritabanı yedeği |
0 9 * * 1-5 | Hafta içi her gün 09.00 | Günlük satış raporu |
30 3 * * 0 | Her pazar 03.30 | Haftalık log temizliği |
0 4 1 * * | Her ayın 1'i 04.00 | Aylık fatura ya da arşiv |
@reboot | Açılıştan sonra bir kez | Geçici klasör hazırlığı |
Saatleri sunucunun zaman dilimine göre okuduğunuzu unutmayın. Ayrıca bir ifadeyi canlıya almadan önce sonraki birkaç çalışma zamanını kâğıt üzerinde ya da sağlam bir hesaplayıcıyla doğrulamanız, "her ay" sandığınız bir görevin "her gün" çalışmasını engeller.
Ne zaman cron'u kendiniz yönetmemelisiniz?
Cron güçlü ama affetmeyen bir araçtır. Bazı durumlarda işi hosting sağlayıcınıza ya da sunucu yöneticinize bırakmak daha doğru karardır; dürüst olmak gerekirse biz de müşterilerimize bunu sık söylüyoruz.
- Yönetilen (managed) hosting kullanıyorsanız sağlayıcı genellikle yedek ve bakım görevlerini kendisi zamanlar. Aynı işi ikinci kez kurmak çakışma yaratır.
- Görev root yetkisi istiyorsa ve sunucuda root ile çalışma deneyiminiz yoksa, bir hata tüm sistemi etkileyebilir.
- Görev, ödeme, fatura ya da müşteri verisi gibi kritik bir akışı yönetiyorsa izleme, uyarı ve geri dönüş planı olmadan kurmayın.
- Paylaşımlı hostingte sağlayıcının sıklık sınırı varsa, sınırı zorlamak yerine destek ekibiyle konuşun.
Hosting seçerken cron erişimi, SSH ve yedekleme politikası gibi kriterleri baştan sormak bu tür sorunları azaltır; kontrol listesi için web sitesi için hosting seçimi yazımıza göz atın. Sitenizi baştan doğru altyapıyla kurmak istiyorsanız web tasarım hizmetimiz kapsamında planlı görevleri de planlıyoruz.
Sonuç: cron job kurarken kısa kontrol listesi
Cron job kurmak tek satırlık bir iş gibi durur; ancak o satırın yıllarca sessizce doğru çalışması birkaç alışkanlığa bağlıdır. Özetle şu listeyi her yeni görevde uygulayın:
- Komutu önce terminalde elle çalıştırın.
- Programları ve dosyaları tam yolla yazın.
- Çıktıyı bir log dosyasına yönlendirin.
- Yüzde işaretlerini kaçırın ya da betiğe taşıyın.
- Uzun sürebilecek görevlere
flock -nekleyin. - Zaman dilimini ve saat senkronunu kontrol edin.
- Görevi gereken en düşük yetkili kullanıcıyla çalıştırın.
- Düzenlemeden önce
crontab -lile yedek alın.
Bu sekiz adım, karşılaştığımız cron sorunlarının büyük kısmını daha oluşmadan önler. Sonuçta iyi kurduğunuz bir cron görevi gözden uzak kalır: yedekleriniz birikir, raporlar gelir, WordPress yazıları zamanında yayına çıkar ve siz bunlarla hiç uğraşmazsınız.



