Linux'ta Cron: tarih, kullanım ve cihaz

Linux'ta Cron: tarih, kullanım ve cihaz

Klasik, mutlu saatlerin izlemediğini yazdı. O çılgın zamanlarda ne programcılar ne de Unix vardı, ancak bugün programcılar kesin olarak biliyorlar: Cron onlar yerine zamanı takip edecek.

Komut satırı yardımcı programları benim için hem zayıflık hem de angarya. sed, awk, wc, Cut ve diğer eski programlar her gün sunucularımızda scriptler tarafından çalıştırılmaktadır. Birçoğu, aslen 70'lerden kalma bir zamanlayıcı olan cron için görevler olarak tasarlandı.

Uzun bir süre cron'u ayrıntılara girmeden yüzeysel olarak kullandım ancak bir gün bir betiği çalıştırırken bir hatayla karşılaştığımda onu iyice incelemeye karar verdim. Bu makale bu şekilde ortaya çıktı, yazarken POSIX crontab'a, popüler Linux dağıtımlarındaki ana cron seçeneklerine ve bazılarının yapısına aşina oldum.

Linux kullanıyor musunuz ve cron görevlerini mi çalıştırıyorsunuz? Unix'teki sistem uygulama mimarisiyle ilgileniyor musunuz? O halde yola çıkıyoruz!

Içerik

Türlerin Kökeni

Kullanıcı veya sistem programlarının periyodik olarak çalıştırılması tüm işletim sistemlerinde bariz bir gerekliliktir. Bu nedenle programcılar, görevleri merkezi olarak planlamalarına ve yürütmelerine olanak tanıyan hizmetlere olan ihtiyacı uzun zaman önce fark ettiler.

Unix benzeri işletim sistemlerinin kökenleri, ünlü Ken Thompson da dahil olmak üzere geçen yüzyılın 7'lerinde Bell Laboratuvarlarında geliştirilen Unix Sürüm 70'ye kadar uzanıyor. Sürüm 7 Unix ayrıca düzenli olarak çalışan süper kullanıcı görevleri için bir hizmet olan cron'u da içeriyordu.

Tipik bir modern cron basit bir programdır, ancak orijinal sürümün işletim algoritması daha da basittir: hizmet dakikada bir uyanır, tek bir dosyadan (/etc/lib/crontab) görevlerin bulunduğu bir tabloyu okur ve o anda gerçekleştirilmesi gereken görevleri süper kullanıcı olarak belirler.

Daha sonra, basit ve kullanışlı hizmetin geliştirilmiş versiyonları tüm Unix benzeri işletim sistemleriyle birlikte sağlandı.

Crontab formatının genelleştirilmiş açıklamaları ve yardımcı programın çalışmasının temel ilkeleri, 1992 yılında Unix benzeri işletim sistemlerinin ana standardına (POSIX) dahil edildi ve böylece fiili bir standarttan cron, hukuki bir standart haline geldi.

1987 yılında, Unix kullanıcılarına cron istekleri konusunda anket yapan Paul Vixie, geleneksel cronun bazı sorunlarını düzelten ve tablo dosyalarının sözdizimini genişleten arka plan programının başka bir versiyonunu yayınladı.

Vixie cron'un üçüncü sürümüyle birlikte POSIX gereksinimlerini karşılamaya başladı, ayrıca programın liberal bir lisansı vardı veya daha doğrusu README'deki istekler dışında hiçbir lisans yoktu: yazar garanti vermez, yazarın adı silinemez ve program yalnızca kaynak koduyla birlikte satılabilir. Bu gereksinimlerin o yıllarda popülerlik kazanan özgür yazılım ilkeleriyle uyumlu olduğu ortaya çıktı, bu nedenle 90'ların başında ortaya çıkan bazı önemli Linux dağıtımları Vixie cron'u sistem olarak aldı ve bugün hala geliştirmeye devam ediyor.

Özellikle Red Hat ve SUSE, Vixie cron - cronie çatalını geliştiriyor ve Debian ve Ubuntu, birçok yamayla birlikte Vixie cron'un orijinal sürümünü kullanıyor.

Öncelikle POSIX'te açıklanan kullanıcı yardımcı programı crontab'ı tanıyalım, ardından Vixie cron'da sağlanan sözdizimi uzantılarına ve popüler Linux dağıtımlarında Vixie cron varyasyonlarının kullanımına bakacağız. Ve son olarak, pastanın üzerindeki kiraz, cron arka plan programı cihazının analizidir.

POSIX crontab'ı

Orijinal cron her zaman süper kullanıcı için çalıştıysa, modern zamanlayıcılar genellikle daha güvenli ve kullanışlı olan sıradan kullanıcıların görevleriyle ilgilenir.

Cron'lar iki programdan oluşan bir set olarak sağlanır: sürekli çalışan cron arka plan programı ve kullanıcılara sunulan crontab yardımcı programı. İkincisi, sistemdeki her kullanıcıya özel görev tablolarını düzenlemenizi sağlarken arka plan programı, kullanıcı ve sistem tablolarından görevleri başlatır.

В POSIX standardı arka plan programının davranışı hiçbir şekilde tanımlanmamıştır ve yalnızca kullanıcı programı resmileştirilmiştir crontab. Kullanıcı görevlerini başlatmaya yönelik mekanizmaların varlığı elbette ima edilmiştir, ancak ayrıntılı olarak açıklanmamıştır.

Crontab yardımcı programını çağırarak dört şey yapabilirsiniz: düzenleyicide kullanıcının görev tablosunu düzenlemek, tabloyu bir dosyadan yüklemek, mevcut görev tablosunu göstermek ve görev tablosunu temizlemek. Crontab yardımcı programının nasıl çalıştığına dair örnekler:

crontab -e # редактировать таблицу задач
crontab -l # показать таблицу задач
crontab -r # удалить таблицу задач
crontab path/to/file.crontab # загрузить таблицу задач из файла

çağrıldığında crontab -e standart ortam değişkeninde belirtilen düzenleyici kullanılacaktır EDITOR.

Görevlerin kendileri aşağıdaki formatta açıklanmıştır:

# строки-комментарии игнорируются
#
# задача, выполняемая ежеминутно
* * * * * /path/to/exec -a -b -c
# задача, выполняемая на 10-й минуте каждого часа
10 * * * * /path/to/exec -a -b -c
# задача, выполняемая на 10-й минуте второго часа каждого дня и использующая перенаправление стандартного потока вывода
10 2 * * * /path/to/exec -a -b -c > /tmp/cron-job-output.log

Kayıtların ilk beş alanı: dakika [1..60], saat [0..23], ayın günleri [1..31], aylar [1..12], haftanın günleri [0. .6], burada 0 Pazar'dır. Son altıncı alan, standart komut yorumlayıcısı tarafından yürütülecek bir satırdır.

İlk beş alanda değerler virgülle ayrılmış olarak listelenebilir:

# задача, выполняемая в первую и десятую минуты каждого часа
1,10 * * * * /path/to/exec -a -b -c

Veya bir tire işaretiyle:

# задача, выполняемая в каждую из первых десяти минут каждого часа
0-9 * * * * /path/to/exec -a -b -c

Görev planlamaya kullanıcı erişimi POSIX'te sırasıyla crontab'a erişimi olan kullanıcıları ve programa erişimi olmayan kullanıcıları listeleyen cron.allow ve cron.deny dosyaları tarafından düzenlenir. Standart, bu dosyaların konumunu hiçbir şekilde düzenlemez.

Standarda göre başlatılan programlara en az dört ortam değişkeninin aktarılması gerekir:

  1. HOME - kullanıcının ana dizini.
  2. LOGNAME — kullanıcı girişi.
  3. PATH, standart sistem yardımcı programlarını bulabileceğiniz yoldur.
  4. SHELL — kullanılan komut yorumlayıcısının yolu.

Özellikle POSIX, bu değişkenlerin değerlerinin nereden geldiğine dair hiçbir şey söylemiyor.

En çok satan - Vixie cron 3.0pl1

Popüler cron çeşitlerinin ortak atası, 3.0 yılında comp.sources.unix e-posta listesinde tanıtılan Vixie cron 1pl1992'dir. Bu sürümün ana özelliklerini daha ayrıntılı olarak ele alacağız.

Vixie cron iki programla gelir (cron ve crontab). Her zamanki gibi arka plan programı, sistem görev tablosundaki ve bireysel kullanıcı görev tablolarındaki görevleri okumak ve çalıştırmaktan sorumludur ve crontab yardımcı programı, kullanıcı tablolarını düzenlemekten sorumludur.

Görev tablosu ve yapılandırma dosyaları

Süper kullanıcı görev tablosu /etc/crontab'da bulunur. Sistem tablosunun sözdizimi, Vixie cron'un sözdizimine karşılık gelir; ancak içindeki altıncı sütun, görevin adına başlatıldığı kullanıcının adını belirtir:

# Запускается ежеминутно от пользователя vlad
* * * * * vlad /path/to/exec

Normal kullanıcı görevi tabloları /var/cron/tabs/username konumunda bulunur ve aynı sözdizimini kullanır. Crontab yardımcı programını kullanıcı olarak çalıştırdığınızda bunlar düzenlenen dosyalardır.

Crontab'a erişimi olan kullanıcıların listeleri /var/cron/allow ve /var/cron/deny dosyalarında yönetilir; burada kullanıcı adını ayrı bir satıra girmeniz yeterlidir.

Genişletilmiş sözdizimi

POSIX crontab ile karşılaştırıldığında Paul Vixey'in çözümü, yardımcı programın görev tablolarının sözdiziminde çok sayıda yararlı değişiklik içeriyor.

Yeni bir tablo sözdizimi kullanıma sunuldu: örneğin, haftanın günlerini veya ayları ada göre belirtebilirsiniz (Pzt, Salı vb.):

# Запускается ежеминутно по понедельникам и вторникам в январе
* * * Jan Mon,Tue /path/to/exec

Görevlerin başlatılacağı adımı belirleyebilirsiniz:

# Запускается с шагом в две минуты
*/2 * * * Mon,Tue /path/to/exec

Adımlar ve aralıklar karıştırılabilir:

# Запускается с шагом в две минуты в первых десять минут каждого часа
0-10/2 * * * * /path/to/exec

Her zamanki söz dizimine sezgisel alternatifler desteklenir (yeniden başlatma, yıllık, yıllık, aylık, haftalık, günlük, gece yarısı, saatlik):

# Запускается после перезагрузки системы
@reboot /exec/on/reboot
# Запускается раз в день
@daily /exec/daily
# Запускается раз в час
@hourly /exec/daily

Görev yürütme ortamı

Vixie cron, çalışan uygulamaların ortamını değiştirmenize olanak tanır.

USER, LOGNAME ve HOME ortam değişkenleri yalnızca arka plan programı tarafından sağlanmaz, aynı zamanda bir dosyadan alınır. passwd. PATH değişkeni "/usr/bin:/bin" olarak ayarlanır ve SHELL değişkeni "/bin/sh" olarak ayarlanır. Kullanıcı tablolarında LOGNAME dışındaki tüm değişkenlerin değerleri değiştirilebilir.

Bazı ortam değişkenleri (en önemlisi SHELL ve HOME), görevi yürütmek için cron'un kendisi tarafından kullanılır. Özel görevleri çalıştırmak için standart sh yerine bash kullanmak şöyle görünebilir:

SHELL=/bin/bash
HOME=/tmp/
# exec будет запущен bash-ем в /tmp/
* * * * * /path/to/exec

Sonuçta tabloda tanımlanan tüm ortam değişkenleri (cron tarafından kullanılan veya süreç tarafından ihtiyaç duyulan) çalışan göreve aktarılacaktır.

Dosyaları düzenlemek için crontab, VISUAL veya EDITOR ortam değişkeninde belirtilen düzenleyiciyi kullanır. Crontab'ın çalıştırıldığı ortamda bu değişkenler tanımlanmış değilse "/usr/ucb/vi" kullanılır (ucb muhtemelen Berkeley'deki Kaliforniya Üniversitesi'dir).

Debian ve Ubuntu'da cron

Debian ve türev dağıtımlarının geliştiricileri şunları yayınladı: son derece değiştirilmiş versiyon Vixie cron sürüm 3.0pl1. Tablo dosyalarının söz diziminde hiçbir farklılık yoktur; kullanıcılar için aynı Vixie cron'dur. En Büyük Yeni Özellik: Destek syslog, SELinux и PAM.

Daha az fark edilen ancak somut değişiklikler, yapılandırma dosyalarının ve görev tablolarının konumunu içerir.

Debian'daki kullanıcı tabloları /var/spool/cron/crontabs dizininde bulunur, sistem tablosu hala oradadır - /etc/crontab'da. Debian paketine özgü görev tabloları /etc/cron.d dosyasına yerleştirilir ve cron arka plan programı bunları otomatik olarak okur. Kullanıcı erişim kontrolü /etc/cron.allow ve /etc/cron.deny dosyaları tarafından kontrol edilir.

Varsayılan kabuk hala /bin/sh'dir ve Debian'da POSIX uyumlu küçük bir kabuktur. tire, herhangi bir yapılandırma okunmadan başlatıldı (etkileşimsiz modda).

Debian'ın en son sürümlerinde Cron'un kendisi systemd aracılığıyla başlatılır ve başlatma yapılandırması /lib/systemd/system/cron.service dosyasında görüntülenebilir. Hizmet yapılandırmasında özel bir şey yoktur; her kullanıcının crontab'ında doğrudan bildirilen ortam değişkenleri aracılığıyla daha ince görev yönetimi yapılabilir.

RedHat, Fedora ve CentOS'ta dost

ahbap — Vixie cron sürüm 4.1'in çatalı. Debian'da olduğu gibi sözdizimi değişmedi ancak PAM ve SELinux desteği, küme halinde çalışma, inotify kullanarak dosyaları izleme ve diğer özellikler eklendi.

Varsayılan konfigürasyon olağan yerlerdedir: sistem tablosu /etc/crontab'dadır, paketler tablolarını /etc/cron.d'ye koyar, kullanıcı tabloları /var/spool/cron/crontabs'a gider.

Arka plan programı systemd kontrolü altında çalışır, hizmet yapılandırması /lib/systemd/system/crond.service'dir.

Red Hat benzeri dağıtımlarda, başlangıçta standart bash olan /bin/sh varsayılan olarak kullanılır. Cron işlerini /bin/sh aracılığıyla çalıştırırken, bash kabuğunun POSIX uyumlu modda başladığını ve herhangi bir ek yapılandırmayı okumadığını, etkileşimli olmayan modda çalıştığını unutmayın.

SLES ve openSUSE'de dost

Alman dağıtımı SLES ve türevi openSUSE aynı cronie'yi kullanıyor. Buradaki arka plan programı da systemd altında başlatılır, hizmet yapılandırması /usr/lib/systemd/system/cron.service konumunda bulunur. Yapılandırma: /etc/crontab, /etc/cron.d, /var/spool/cron/tabs. /bin/sh, POSIX uyumlu etkileşimli olmayan modda çalışan aynı bash'tır.

Vixie cron cihazı

Cronun modern torunları, Vixie cron'a kıyasla radikal bir şekilde değişmedi, ancak yine de programın ilkelerini anlamak için gerekli olmayan yeni özellikler edindiler. Bu uzantıların çoğu kötü tasarlanmış ve kodu karıştırıyor. Paul Vixey'nin orijinal cron kaynak kodunu okumak bir zevktir.

Bu nedenle, her iki geliştirme dalında da ortak olan bir cron programı örneğini kullanarak cron cihazını analiz etmeye karar verdim - Vixie cron 3.0pl1. Okumayı zorlaştıran ifdef'leri kaldırarak ve küçük ayrıntıları atlayarak örnekleri basitleştireceğim.

İblisin işi birkaç aşamaya ayrılabilir:

  1. Programın başlatılması.
  2. Çalıştırılacak görevlerin listesinin toplanması ve güncellenmesi.
  3. Ana cron döngüsü çalışıyor.
  4. Bir görev başlatın.

Sırasıyla bunlara bakalım.

Başlatma

Başlatıldığında, süreç argümanlarını kontrol ettikten sonra cron, SIGCHLD ve SIGHUP sinyal işleyicilerini yükler. Birincisi alt sürecin sonlandırılmasıyla ilgili bir günlük girişi yapar, ikincisi ise günlük dosyasının dosya tanımlayıcısını kapatır:

signal(SIGCHLD, sigchld_handler);
signal(SIGHUP, sighup_handler);

Cron arka plan programı sistemde her zaman tek başına, yalnızca süper kullanıcı olarak ve ana cron dizininden çalışır. Aşağıdaki çağrılar, daemon işleminin PID'sini içeren bir kilit dosyası oluşturur, kullanıcının doğru olduğundan emin olun ve mevcut dizini ana dizine değiştirin:

acquire_daemonlock(0);
set_cron_uid();
set_cron_cwd();

İşlemleri başlatırken kullanılacak olan varsayılan yol ayarlandı:

setenv("PATH", _PATH_DEFPATH, 1);

Daha sonra süreç "arka planlı hale getirilir": çatalı çağırarak sürecin bir alt kopyasını ve alt süreçte yeni bir oturumu (setsid'i çağırarak) oluşturur. Ana sürece artık ihtiyaç duyulmaz ve çıkar:

switch (fork()) {
case -1:
    /* критическая ошибка и завершение работы */
    exit(0);
break;
case 0:
    /* дочерний процесс */
    (void) setsid();
break;
default:
    /* родительский процесс завершает работу */
    _exit(0);
}

Ana sürecin sonlandırılması, kilit dosyasındaki kilidi serbest bırakır. Ayrıca dosyadaki PID'nin alt öğeye güncellenmesi gerekmektedir. Bundan sonra görev veritabanı doldurulur:

/* повторный захват лока */
acquire_daemonlock(0);

/* Заполнение БД  */
database.head = NULL;
database.tail = NULL;
database.mtime = (time_t) 0;
load_database(&database);

Daha sonra cron ana çalışma döngüsüne geçer. Ancak bundan önce görev listesinin yüklenmesine bir göz atmakta fayda var.

Görev listesinin toplanması ve güncellenmesi

Load_database işlevi, görev listesinin yüklenmesinden sorumludur. Ana sistem crontab'ını ve kullanıcı dosyalarının bulunduğu dizini kontrol eder. Dosyalar ve dizin değişmediyse görev listesi yeniden okunmaz. Aksi takdirde yeni bir görev listesi oluşmaya başlar.

Özel dosya ve tablo adlarına sahip bir sistem dosyasının yüklenmesi:

/* если файл системной таблицы изменился, перечитываем */
if (syscron_stat.st_mtime) {
    process_crontab("root", "*system*",
    SYSCRONTAB, &syscron_stat,
    &new_db, old_db);
}

Kullanıcı tablolarını bir döngüye yükleme:

while (NULL != (dp = readdir(dir))) {
    char    fname[MAXNAMLEN+1],
            tabname[MAXNAMLEN+1];
    /* читать файлы с точкой не надо*/
    if (dp->d_name[0] == '.')
            continue;
    (void) strcpy(fname, dp->d_name);
    sprintf(tabname, CRON_TAB(fname));
    process_crontab(fname, fname, tabname,
                    &statbuf, &new_db, old_db);
}

Bundan sonra eski veritabanı yenisiyle değiştirilir.

Yukarıdaki örneklerde, proses_crontab işlev çağrısı, tablo dosya adıyla eşleşen bir kullanıcının var olduğunu doğrular (süper kullanıcı olmadığı sürece) ve ardından load_user'ı çağırır. İkincisi zaten dosyanın kendisini satır satır okuyor:

while ((status = load_env(envstr, file)) >= OK) {
    switch (status) {
    case ERR:
        free_user(u);
        u = NULL;
        goto done;
    case FALSE:
        e = load_entry(file, NULL, pw, envp);
        if (e) {
            e->next = u->crontab;
            u->crontab = e;
        }
        break;
    case TRUE:
        envp = env_set(envp, envstr);
        break;
    }
}

Burada, ya load_env / env_set işlevleri kullanılarak ortam değişkeni ayarlanır (VAR=değer formundaki satırlar) ya da load_entry işlevi kullanılarak görev açıklaması okunur (* * * * * /path/to/exec).

load_entry'nin döndürdüğü girdi varlığı, genel görevler listesinde yer alan bizim görevimizdir. İşlev, zaman biçiminin ayrıntılı bir ayrıştırmasını gerçekleştirir, ancak biz daha çok ortam değişkenlerinin ve görev başlatma parametrelerinin oluşturulmasıyla ilgileniyoruz:

/* пользователь и группа для запуска задачи берутся из passwd*/
e->uid = pw->pw_uid;
e->gid = pw->pw_gid;

/* шелл по умолчанию (/bin/sh), если пользователь не указал другое */
e->envp = env_copy(envp);
if (!env_get("SHELL", e->envp)) {
    sprintf(envstr, "SHELL=%s", _PATH_BSHELL);
    e->envp = env_set(e->envp, envstr);
}
/* домашняя директория */
if (!env_get("HOME", e->envp)) {
    sprintf(envstr, "HOME=%s", pw->pw_dir);
    e->envp = env_set(e->envp, envstr);
}
/* путь для поиска программ */
if (!env_get("PATH", e->envp)) {
    sprintf(envstr, "PATH=%s", _PATH_DEFPATH);
    e->envp = env_set(e->envp, envstr);
}
/* имя пользовтеля всегда из passwd */
sprintf(envstr, "%s=%s", "LOGNAME", pw->pw_name);
e->envp = env_set(e->envp, envstr);

Ana döngü mevcut görev listesiyle çalışır.

Ana döngü

Unix Sürüm 7'deki orijinal cron oldukça basit bir şekilde çalıştı: yapılandırmayı bir döngü halinde yeniden okudu, geçerli dakikanın görevlerini bir süper kullanıcı olarak başlattı ve bir sonraki dakikanın başına kadar uyudu. Eski makinelerdeki bu basit yaklaşım çok fazla kaynak gerektiriyordu.

SysV'de arka plan programının ya görevin tanımlandığı en yakın dakikaya kadar ya da 30 dakika boyunca uyku moduna geçtiği alternatif bir sürüm önerildi. Bu modda yapılandırmayı yeniden okumak ve görevleri kontrol etmek için daha az kaynak tüketildi, ancak görev listesinin hızlı bir şekilde güncellenmesi zahmetli hale geldi.

Vixie cron dakikada bir görev listelerini kontrol etmeye geri döndü, neyse ki 80'lerin sonunda standart Unix makinelerinde önemli ölçüde daha fazla kaynak vardı:

/* первичная загрузка задач */
load_database(&database);
/* запустить задачи, поставленные к выполнению после перезагрузки системы */
run_reboot_jobs(&database);
/* сделать TargetTime началом ближайшей минуты */
cron_sync();
while (TRUE) {
    /* выполнить задачи, после чего спать до TargetTime с поправкой на время, потраченное на задачи */
    cron_sleep();

    /* перечитать конфигурацию */
    load_database(&database);

    /* собрать задачи для данной минуты */
    cron_tick(&database);

    /* перевести TargetTime на начало следующей минуты */
    TargetTime += 60;
}

cron_sleep işlevi, job_runqueue (görevleri numaralandır ve çalıştır) ve do_command (her bir görevi çalıştır) işlevlerini çağırarak görevlerin yürütülmesinde doğrudan yer alır. Son işlev daha ayrıntılı olarak incelenmeye değer.

Bir görevi çalıştırma

do_command işlevi iyi bir Unix stilinde yürütülür, yani görevi eşzamansız olarak gerçekleştirmek için bir çatal yapar. Ana süreç görevleri başlatmaya devam eder, alt süreç ise görev sürecini hazırlar:

switch (fork()) {
case -1:
    /*не смогли выполнить fork */
    break;
case 0:
    /* дочерний процесс: на всякий случай еще раз пробуем захватить главный лок */
    acquire_daemonlock(1);
    /* переходим к формированию процесса задачи */
    child_process(e, u);
    /* по завершению дочерний процесс заканчивает работу */
    _exit(OK_EXIT);
    break;
default:
    /* родительский процесс продолжает работу */
    break;
}

Child_process'de oldukça fazla mantık vardır: daha sonra postaya göndermek için standart çıktıyı ve hata akışlarını kendi üzerine alır (eğer MAILTO ortam değişkeni görev tablosunda belirtilmişse) ve son olarak ana işlemi bekler. tamamlanacak görev süreci.

Görev süreci başka bir çataldan oluşur:

switch (vfork()) {
case -1:
    /* при ошибки сразу завершается работа */
    exit(ERROR_EXIT);
case 0:
    /* процесс-внук формирует новую сессию, терминал и т.д.
     */
    (void) setsid();

    /*
     * дальше многословная настройка вывода процесса, опустим для краткости
     */

    /* смена директории, пользователя и группы пользователя,
     * то есть процесс больше не суперпользовательский
     */
    setgid(e->gid);
    setuid(e->uid);
    chdir(env_get("HOME", e->envp));

    /* запуск самой команды
     */
    {
        /* переменная окружения SHELL указывает на интерпретатор для запуска */
        char    *shell = env_get("SHELL", e->envp);

        /* процесс запускается без передачи окружения родительского процесса,
         * то есть именно так, как описано в таблице задач пользователя  */
        execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);

        /* ошибка — и процесс на запустился? завершение работы */
        perror("execl");
        _exit(ERROR_EXIT);
    }
    break;
default:
    /* сам процесс продолжает работу: ждет завершения работы и вывода */
    break;
}

Temel olarak tüm cron budur. Uzak kullanıcıların muhasebeleştirilmesi gibi bazı ilginç ayrıntıları atladım, ancak asıl konunun ana hatlarını çizdim.

Послесловие

Cron, Unix dünyasının en iyi geleneklerine göre yapılmış, şaşırtıcı derecede basit ve kullanışlı bir programdır. Fazladan bir şey yapmıyor ama onlarca yıldır işini harika bir şekilde yapıyor. Ubuntu ile birlikte gelen sürümün kodunu incelemek bir saatten fazla sürmedi ve çok eğlendim! Umarım sizlerle paylaşabilmişimdir.

Sizi bilmem ama aşırı karmaşık ve aşırı soyut eğilimi olan modern programlamanın uzun süredir bu kadar basitliğe yardımcı olmadığını fark etmek beni biraz üzüyor.

Cron'un birçok modern alternatifi vardır: systemd-timer'lar bağımlılıkları olan karmaşık sistemleri düzenlemenize olanak tanır, fcron görevlere göre kaynak tüketimini daha esnek bir şekilde düzenlemenize olanak tanır. Ama kişisel olarak en basit crontab benim için her zaman yeterliydi.

Kısacası Unix'i sevin, basit programlar kullanın ve platformunuzun manasını okumayı unutmayın!

Kaynak: habr.com

Yorum ekle