Web

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

Talha Aslan 16 dakikalık okuma 1 görüntülenme

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:

  1. Dakika: 0 ile 59 arası.
  2. Saat: 0 ile 23 arası.
  3. Ayın günü: 1 ile 31 arası.
  4. Ay: 1 ile 12 arası ya da İngilizce ay adının ilk üç harfi (jan, feb gibi).
  5. 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.sh

Yukarı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-5 hafta 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/10 ise 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.
  • @yearly ve @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 * * 0 ile 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:

  1. Görevi önce elle çalıştırın. Komut terminalde hatasız bitmiyorsa cron'da da bitmez.
  2. Komuttaki her programın tam yolunu bulun: command -v php ya da which php çıktısını not edin.
  3. crontab -e ile kendi tablonuzu açın. İlk açılışta bazı sistemler hangi editörü kullanmak istediğinizi sorar.
  4. Üstüne bir yorum satırı, altına zamanlama satırını yazın ve çıktıyı bir log dosyasına yönlendirin.
  5. Dosyayı kaydedip çıkın. "installing new crontab" benzeri bir mesaj görürseniz tablo yüklenmiştir.
  6. crontab -l ile 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.

KomutNe yapar?Risk ve ipucu
crontab -eTabloyu 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 -lMevcut tabloyu ekrana yazdırır.Yedek almak için çıktıyı bir dosyaya yönlendirin.
crontab -rMevcut tabloyu tamamen kaldırır.Onay sormaz; -e ile tek harf farkı vardır.
crontab -i -rSilmeden önce y/Y onayı ister.Destekleyen sistemlerde güvenli alışkanlık.
crontab -u kullanici -lBaş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).txt

Bu 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.

KonumKim düzenler?Kullanıcı alanıEn uygun durum
Kullanıcı crontab'ı (crontab -e)Hesabın sahibiYok, görev o kullanıcıyla çalışırSite sahibinin kendi betikleri, paylaşımlı hosting
/etc/crontabrootVarDağıtımın kendi bakım görevleri; elle eklemeyi sınırlı tutun
/etc/cron.d/dosyaroot ya da paket yöneticisiVarBir uygulamaya ait görevleri ayrı dosyada toplamak
cPanel Cron JobscPanel hesabıYokSSH erişimi olmayan paylaşımlı hosting
# /etc/cron.d/ornek-uygulama* * * * * www-data /usr/bin/php /var/www/example.com/artisan schedule:run

Kullanı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/bash tanı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.sh

Cron'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:run

Buradaki 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.com

Daha 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.

  1. cPanel'e girip Gelişmiş bölümünden Cron Jobs ekranını açın.
  2. "Cron Email" alanına bildirim almak istediğiniz adresi yazın ya da bildirim istemiyorsanız alanı boş bırakın.
  3. "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.
  4. Command alanına komutun tam yolunu yazın ve görevi ekleyin.
  5. 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>&1

Buradaki 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:

  1. Servis ayakta mı? systemctl status cron ya da RHEL ailesinde systemctl status crond ile kontrol edin.
  2. Satır gerçekten tabloda mı? crontab -l çıktısına bakın; doğru kullanıcının tablosunu incelediğinizden emin olun.
  3. Cron görevi tetikledi mi? Sistem günlüğünde ilgili dakikada "CRON" kaydı arayın.
  4. Yol doğru mu? Programları ve dosyaları tam yolla yazdığınızı kontrol edin.
  5. İ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.
  6. 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.
  7. Yüzde işareti var mı? Kaçışsız % komutu böler.
  8. Erişim yasağı var mı? cron.allow dosyası varsa kullanıcınız orada yazmalı; yalnız cron.deny varsa 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/Istanbul ile 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>&1

Kı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.allow ve cron.deny dosyaları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.

İfadeAnlamıÖrnek kullanım
*/5 * * * *Her 5 dakikada birKuyruk işleme ve stok senkronu
*/15 * * * *Her 15 dakikada birWordPress planlı olayları
0 * * * *Her saat başıÖnbellek ısıtma, kur güncelleme
17 2 * * *Her gün 02.17Veritabanı yedeği
0 9 * * 1-5Hafta içi her gün 09.00Günlük satış raporu
30 3 * * 0Her pazar 03.30Haftalık log temizliği
0 4 1 * *Her ayın 1'i 04.00Aylık fatura ya da arşiv
@rebootAçılıştan sonra bir kezGeç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:

  1. Komutu önce terminalde elle çalıştırın.
  2. Programları ve dosyaları tam yolla yazın.
  3. Çıktıyı bir log dosyasına yönlendirin.
  4. Yüzde işaretlerini kaçırın ya da betiğe taşıyın.
  5. Uzun sürebilecek görevlere flock -n ekleyin.
  6. Zaman dilimini ve saat senkronunu kontrol edin.
  7. Görevi gereken en düşük yetkili kullanıcıyla çalıştırın.
  8. Düzenlemeden önce crontab -l ile 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.

Sıkça Sorulan Sorular

Cron job en sık hangi aralıkla çalışabilir?
Klasik cron'da en kısa aralık bir dakikadır, çünkü servis tabloları dakikada bir kontrol eder. Saniye düzeyinde bir ihtiyaç varsa cron uygun araç değildir; sürekli çalışan bir servis ya da kuyruk işçisi daha doğru çözümdür. Paylaşımlı hostingte sağlayıcılar ayrıca bir alt sınır koyabilir, bu nedenle sağlayıcınızın belgelerine bakın.
Crontab dosyası nerede saklanır, doğrudan düzenleyebilir miyim?
Kullanıcı crontab'ları dağıtıma göre /var/spool altında bir klasörde durur, ancak bu dosyaları doğrudan düzenlemenizi önermeyiz. crontab -e komutu dosyayı açar, kaydederken söz dizimini kontrol eder ve servise değişikliği bildirir. Elle düzenleme bu kontrolleri atlar. Sistem görevleri için ise /etc/cron.d altındaki dosyaları root yetkisiyle düzenlersiniz.
crontab -r ile sildiğim görevleri geri getirebilir miyim?
Hayır, crontab -r onay sormadan tabloyu kaldırır ve cron'un kendi geri alma mekanizması yoktur. Daha önce crontab -l çıktısını bir dosyaya kaydettiyseniz crontab dosya_adi komutuyla geri yüklersiniz. Kaydınız yoksa sunucu yedeğinden ya da hosting sağlayıcınızdan yardım istemeniz gerekir. Bu yüzden düzenlemeden önce yedek almayı alışkanlık haline getirin.
WordPress'te DISABLE_WP_CRON açmak siteyi hızlandırır mı?
Kısmen, çünkü WP-Cron artık her sayfa yüklemesinde zamanlanmış görev kontrolü yapmaz. Asıl kazanç ise güvenilirliktir: görevler ziyaretçi trafiğinden bağımsız, belirlediğiniz aralıkta çalışır. Ancak satırı ekleyip sistem cron'unu kurmazsanız zamanlanmış yazılar ve e-postalar hiç çalışmaz. Değişiklikten sonra ilk birkaç çalışmayı log üzerinden kontrol edin.
Cron mu systemd timer mı kullanmalıyım?
Basit ve tekrar eden görevler için cron yeterlidir ve hemen her sistemde, paylaşımlı hosting dahil, bulunur. systemd timer ise bağımlılık tanımlama, kaçırılan çalışmayı telafi etme ve journal ile bütünleşik log gibi ek özellikler sunar. Root erişiminiz olan bir VPS'te karmaşık görevler için timer, paylaşımlı hostingte ise cron daha pratik seçimdir.
Cron görevim çalışıyor mu, nasıl anlarım?
En güvenilir yol, görevin çıktısını tarih damgasıyla bir log dosyasına yazdırmaktır. Ayrıca sistem günlüğünde CRON kayıtlarına bakarak servisin görevi tetikleyip tetiklemediğini görürsünüz. Kritik görevlerde başarılı bitişte bir dosyanın zamanını güncelleyip bunu izleme sistemiyle kontrol etmek, sessiz arızaları erkenden yakalamanızı sağlar.
  • cron job
  • crontab
  • Linux sunucu
  • cPanel
  • WordPress wp-cron
  • flock
  • sunucu yönetimi
Paylaş:
Talha Aslan

Google Partner dijital pazarlama uzmanı. 2012’den beri SEO, Google Ads, web tasarım ve e-ticaret projelerinde sahada; bu blogda gördüğünüz her yazı o deneyimden çıkar.

Sıradaki proje

Projenizi konuşalım.

Talebiniz doğrudan Talha Aslan ve ekibine ulaşır: stratejiyi Talha kurar, uygulamayı deneyimli ekip yürütür. İlk istişare ücretsizdir; hedefinizi dinler, net bir yol haritasıyla döneriz.