UNIX tipi işletim sistemlerinde zamanlanmış görevler için cron kullanılır. Bu daemon çok küçük farklılıklar ile tüm UNIX tipi sistemler içerisinde bulunur. Cron ismini Chronos'tan almıştır.

UNIX'lerde bu tip alıntılara çokça rastlanır. Zaman temelli bir daemon olan cron için oldukça uygun bir isim. Cron servisinin en küçük zaman aralığı 1 dakikadır. Yani tekrar eden işlemleri en kısa 1 dakikalık aralıklarla çalıştırabilir. Fakat bu yazıda, 1 dakikadan kısa sürelerde işlemleri nasıl çalıştırabileceğimizi de göreceğiz.

Crontab

Cron servisi crontab(Cron Table) ile işletilir. Çok karmaşık olmayan bir ifade dizgisine sahiptir.
Sistem çapında bir crontab dosyası genellikle /etc altında bulunur ve root erişimi ile müdahale edilebilir. Ancak bununla birlikte diğer kullanıcılar da kendi crontab dosyalarını oluşturabilirler. Bu dosya içerisindeki her bir satır, bir görev veya komut anlamını taşımaktadır.

Örnek bir crontab satırı şöyle olabilir;

*/1 * * * * /usr/scripts/test.sh > /dev/null 2>&1

Yukarıdaki dizgi test.sh ismindeki shell scrpiti her 60 saniyede yani her 1 dakikada calıştıracaktır.

Bu satırı daha iyi anlamak için aşağıdaki tabloya göz atın. Satır sonunda görülen > /dev/null 2>&1 ifadesini ve açıklamasını yazının ilerleyen satırlarında bulabilirsiniz.

* * * * * /yol/komut arguman 
┬ ┬ ┬ ┬ ┬ 
│ │ │ │ │ 
│ │ │ │ │ 
│ │ │ │ └───── Haftanın Günü. (0 = Pazar) 
│ │ │ └────────── Ay (1-12) 
│ │ └─────────────── Ayın Günü (1 - 31) 
│ └──────────────────── Saat (0 - 23) 
└───────────────────────── Dakika (0 - 59)

Her satırın başında bulunan # ifadesini görmezden gelin. Zaten aşağı yukarı işlevi bu. Başında bulunduğu her ifadenin bir yorum olduğu ve işlenmemesi gerektiğini ifade ediyor.

!!! Crontab içerisinde pasif hale getirmek istediğiniz bir görevin ilk satırına # koymanız yeterli

İlk örnekte olduğu gibi cron ifadeleri içerisinde birtakım operatörler kullanabiliriz. Bu operatörlerden bazıları gruplanmış halde modern UNIX tipi sistemlerde bulunabilirler. Cron birçok farklı şekilde türemiştir. Anacron, dcron ve fcron bunlardan birkaçıdır. Bu operatörlerin bir kısmı kullandığınız cron türevinde bulunmayabilir. Ancak elimden geldiğince genel geçer anlatmaya çalışacağım.

Cron Operatörler

Asterisk ( * )

Asterisk operatörü bulunduğu kolonun her aldığı değeri kapsar. Yani Eğer haftanın her gününü ifade etmek istiyorsanız, 5. kolona tek tek hafta günlerini yazmak yerine * kullanabilirsiniz.

Örnek:

* * * * * /usr/scripts/test.sh > /dev/null 2>&1

Yukarıdaki örnekte ifade aslında her dakika çalışacak şekildedir. Çünkü cron cycle 60 saniyede bir çalışır.

Tire ( - )

Bu operatör bir değer aralığı belirtmek için kullanılır. Her saatin 10. dakikasından 20. dakikasına kadar bir işleme ihtiyacınız olabilir.

Örnek:

10-20 * * * * /usr/scripts/test.sh > /dev/null 2>&1

Virgül ( , )

Bu operatör tıpkı AND kapısı veya birçok C kökenli dildeki && operatörüne denk gelir. Her saatin 10. ve 20. dakikasını ifade edebiliriz.

Örnek:*

10,20 * * * * /usr/scripts/test.sh > /dev/null 2>&1

Slash ( / )

Kelimelerle ifade etmenin biraz kafa karıştırıcı olduğu bir operatör. Daha önce her saatin 10. dakikasından 20. dakikasına kadar çalışan bir ifade yazmıştık. Cron her 60 saniyede bir tetiklendiği için ifademizin bu zaman aralığında her dakikada bir çalışacağını biliyorduk. Peki her 2 dakikada bir çalışmasını istiyorsak?

Örnek:

10-20/2 * * * * /usr/scripts/test.sh > /dev/null 2>&1

Bu operatörlerin yanında, bazı önceden belirlenmiş ifadelerde söz konusudur. Bu ifadeleri fazla detaylandırmadan bir tablo halinde göstermek daha iyi olacaktır.

Çıktı Kontrolü

Cron ifadelerimiz çalışırken, mümkün olduğunca çıktı vermemeleri iyidir. Çünkü bu çıktı tipine göre stdout veya stderr streamlerine gidecektir. Bu streamleri bazı sistemler e-posta ile(ki çoğunlukla local-delivery) ulaştırmaya çalışır. Cron scriptlerimizin yahut komutlarımızın doğru çalıştığından emin olup bu gereksiz çıktıları engellemek en doğru harekettir.

UNIX tipi ve birçok diğer işletim sisteminde > operatörü çıktı yönlendirmek için kullanılır.

Örnek:

echo "Kodzilla" > kodzilla.txt

Yukarıdaki örnekte eksik bir ifadeyle ekrana, doğru bir ifadeyle stdout'a Kodzilla stringini gönderiyoruz. Çünkü echo tam olarak bunu yapar. Ancak bu çıktıyı > operatörü ile kodzilla.txt dosyasına yönlendirdik.

Bazı özel ifadeler yardımıyla, stdout ve stderr kontrole sahip olmadığımız zamanlarda ve öngöremediğimiz çıktıları elimine edebilir ve /dev/null  aygıtına yönlendirebiliriz. /dev/null UNIX tipi ve birçok farklı işletim sisteminde bulunur. Kara delik veya dibi olmayan çöp kovası gibi isimleri vardır.

File descriptorlar bu yazının konusu olmadığı için detaylarına girmeden geçeceğim. Burada kullandığımız iki farklı file descriptor var. 2, stderr anlamına gelir. 1 ise stdout. Yazının başındaki ilk örneğe tekrar bakalım.

*/1 * * * * /usr/scripts/test.sh > /dev/null 2>&1

2> ifadesi ile stderr 1'e yani stdouta yönlendirilmiş. Sonraki > operatörü ile stdout /dev/null aygıtına yönlendirilmiş. Böylelikle scrpitimizin tamamen sessizlik içerisinde çalışmasını sağlıyoruz.

Cron ve Saniyeler

Artık bildiğiniz üzere, cron saniyeler değil dakikalar bazında çalışıyor. Yani saniyeler gereken işlerinizde sizi yalnız bırakacaktır. Cron hakkında en çok sorulan sorulardan biri 1 dakikadan daha kısa zaman dilimlerinde çalıştırılıp çalıştırılamayacağıdır.

Hayır. Cron dakikada bir tetiklenebilir. Ancak çözümsüz değil.

Bunu bir senaryo ile örneklendirerek yapalım. Kullanıcılarımızın dönüşlerini aldığımız bir veri tabanımız var. Bu veri tabanındaki tüm veriler bir cron işlemi tarafından dakikada bir kontrol ediliyor ve yeni gelen kayıtlar elimize e-posta şeklinde ulaşıyor. Ancak bu süreyi 30 saniyeye indirmek istiyoruz.

Cron'un 60 saniyede bir tetikleneceği gerçeğini göz önünde bulundurarak, istediğimiz işlemi çalıştırıldığı anda bir kez yapıp 30 saniye uyuyan ve işlemi tekrar yapan sonra kendin sonlandıran bir script işimize yarayacaktır.

Crontab satırı

*/1 * * * * /usr/scripts/test.sh > /dev/null 2>&1

test.sh

#!/bin/bash
echo "Mesaj Icerigi" | mail -s "Mesaj Basligi" eposta@adresi
sleep 30
echo "Mesaj Icerigi" | mail -s "Mesaj Basligi" eposta@adresi

Bu zamanı daha kısaltabilir veya uzatabiliriz elbette. Ancak dikkat edilmesi gereken shell scrpitin işini ne kadar sürede bitirdiğidir. Bu zamanlamayı aksatabilecek en önemli değişkendir.

Güncel olarak çok kullanılmıyor olsa da cron.allow ve cron.deny dosyaları da mevcuttur. İsimlerinden anlaşılacağı üzere bu dosyalar ile sistem yöneticisi bazı kullanıcılar için izin verebilir veya izin vermeyebilir. Fakat güncel olarak pek kullanıldığına tanık olmadım.