it-swarm-tr.com

Crontab'ım neden çalışmıyor ve bu sorunu nasıl giderebilirim?

Bu, cron & crontab kullanımı hakkında bir Kanonik Sor .

Buraya yönlendirildiniz çünkü topluluk sorunuzun yanıtının aşağıda bulunabileceğinden oldukça emin. Sorunuz aşağıda yanıtlanmadıysa, yanıtlar topluluğun size yardım etmesine yardımcı olacak bilgiler toplamanıza yardımcı olacaktır. Bu bilgiler orijinal sorunuzda düzenlenmelidir.

' Crontab'ım neden çalışmıyor ve nasıl giderebilirim? ' cevabı aşağıda görülebilir. Bu, crontab vurgulanmış olarak cron sistemini ele alır.

246
Eric Leschinski

Crontab ile ilgili tüm sorunlarınız/sorunlarınız nasıl giderilir (Linux)


Bu bir topluluk wiki , bu cevapta yanlış bir şey fark ederseniz veya ek bilgi alırsanız, lütfen düzenleyin.


İlk olarak, temel terminoloji:

  • cron (8) zamanlanmış komutları yürüten arka plan programıdır.
  • crontab (1) , kullanıcı crontab (5) dosyalarını değiştirmek için kullanılan programdır.
  • crontab (5) , cron (8) için talimatlar içeren bir kullanıcı dosyasıdır.

Sonra, cron hakkında eğitim:

Sistemdeki her kullanıcının kendi crontab dosyası olabilir. Kök ve kullanıcı crontab dosyalarının konumu sisteme bağlıdır, ancak genellikle /var/spool/cron Altındadır.

Sistem çapında bir /etc/crontab Dosyası vardır, /etc/cron.d Dizini, cron tarafından da okunan ve işlenen crontab parçaları içerebilir. Bazı Linux dağıtımlarında da (örneğin, Red Hat) /etc/cron.{hourly,daily,weekly,monthly} Dizini vardır, bunlar içinde her saat/gün/hafta/ay çalıştırılacak komut dosyaları vardır.

root her zaman crontab komutunu kullanabilir; normal kullanıcılara erişim izni verilebilir veya verilmeyebilir. Crontab dosyasını crontab -e Komutuyla düzenlediğinizde ve kaydettiğinizde, crond dosyayı temel geçerlilik açısından kontrol eder, ancak crontab dosyanızın doğru oluşturulduğunu garanti etmez. Hangi kullanıcıların cron kullanamayacağını belirten cron.deny Adlı bir dosya var. cron.deny Dosya konumu sisteme bağlıdır ve silinebilir, bu da tüm kullanıcıların cron kullanmasına izin verir.

Bilgisayar açık değilse veya crond daemon çalışmıyorsa ve bir komutun çalıştırılacağı tarih/saat geçtiyse, crond yakalanmaz ve geçmiş sorguları çalıştırmaz.

crontab ayrıntıları, bir komutun nasıl formüle edileceği:

Bir crontab komutu tek bir satırla gösterilir. Bir komutu birden çok satıra genişletmek için \ Kullanamazsınız. Karma (#) İşareti, bu satırdaki herhangi bir şeyin cron tarafından yok sayıldığı anlamına gelen bir yorumu temsil eder. Öncü boşluk ve boş satırlar yoksayılır.

Komutunuzda yüzde (%) İşaretini kullanırken ÇOK dikkatli olun. Kaçmadıkları sürece \% Yeni satırlara dönüştürülür ve ilk kaçan % 'Dan sonraki her şey stdin komutunuza geçirilir.

Crontab dosyaları için iki biçim vardır:

  • Kullanıcı crontabs

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  *   command to be executed
    
  • Sistem çapında /etc/crontab Ve /etc/cron.d Parçaları

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  * user-name  command to be executed
    

İkincisinin bir kullanıcı adı gerektirdiğine dikkat edin. Komut, adlandırılmış kullanıcı olarak çalıştırılacaktır.

Satırın ilk 5 alanı komutun çalıştırılması gereken süreleri gösterir. Zaman belirtiminde sayıları veya varsa gün/ay adlarını kullanabilirsiniz.

  • Alanlar boşluklarla veya sekmelerle ayrılır.
  • Bir liste belirtmek için virgül (,) Kullanılır, örneğin 1,4,6,8, yani 1,4,6,8'de çalıştırılır.
  • Aralıklar bir tire işareti ile belirtilir (-) Ve listelerle birleştirilebilir; 1-3,9-12, 1 ile 3 arasında, ardından 9 ile 12 arasında anlamına gelir.
  • / Karakteri bir adımı başlatmak için kullanılabilir, örn. 2/5 yani 2'den başlayarak her 5'ten (2,7,12,17,22 ...) başlar. Sonunu geçmezler.
  • Bir alandaki yıldız işareti (*) O alanın tüm aralığını belirtir (örneğin, dakika alanı için 0-59).
  • Aralık ve adımlar örn. */2, İlgili alan için minimumdan sonra her 2 örn. 0 dakika (0,2 ... 58), 1 ay (1,3 ... 11) vb.

Cron komutlarında hata ayıklama

Postayı kontrol et!

Varsayılan olarak cron, komuttan herhangi bir çıktıyı komutu çalıştırdığı kullanıcıya gönderir. Çıktı yoksa posta olmayacaktır. Cron'un farklı bir hesaba posta göndermesini istiyorsanız, crontab dosyasında MAILTO ortam değişkenini ayarlayabilirsiniz;.

[email protected]
1 2 * * * /path/to/your/command

Çıktıyı kendiniz yakalayın

Stdout ve stderr dosyalarını bir dosyaya yeniden yönlendirebilirsiniz. Çıkışı yakalamak için tam sözdizimi, Shell cron'un ne kullandığına bağlı olarak değişebilir. Tüm çıktıları bir dosyaya /tmp/mycommand.log 'Da kaydeden iki örnek:

1 2 * * * /path/to/your/command &>/tmp/mycommand.log
1 2 * * * /path/to/your/command >/tmp/mycommand.log 2>&1

Günlüklere bak

Cron eylemlerini (kurulumunuza bağlı olarak) genellikle /var/log/cron Veya /var/log/syslog Adresine giden syslog aracılığıyla günlüğe kaydeder.

Gerekirse cron deyimlerini ör.

grep CRON /var/log/syslog 

Artık cron'un temellerini inceledik, dosyaların nerede olduğu ve nasıl kullanılacağı bazı genel sorunlara bakalım.

Cron'un çalışıp çalışmadığını kontrol edin

Cron çalışmıyorsa, komutlarınız zamanlanmayacaktır ...

ps -ef | grep cron | grep -v grep

sana böyle bir şey getirmeli

root    1224   1  0 Nov16 ?    00:00:03 cron

veya

root    2018   1  0 Nov14 ?    00:00:06 crond

Yeniden başlatmazsanız

/sbin/service cron start

veya

/sbin/service crond start

Başka yöntemler de olabilir; dağıtımınızın sağladığı şeyi kullanın.

cron komutunuzu kısıtlı bir ortamda çalıştırır.

Hangi ortam değişkenlerinin kullanılabileceği çok sınırlı olacaktır. Genellikle, $LOGNAME, $HOME Ve $PATH Gibi yalnızca birkaç değişken tanımlanır.

PATH/bin:/usr/bin İle sınırlıdır. "Cron betiğim çalışmıyor" sorunlarının büyük çoğunluğu bu kısıtlayıcı yoldan kaynaklanmaktadır . Komutunuz farklı bir konumdaysa, bunu birkaç şekilde çözebilirsiniz:

  1. Komutunuzun tam yolunu belirtin.

    1 2 * * * /path/to/your/command
    
  2. Crontab dosyasında uygun bir PATH sağlayın

    PATH=/bin:/usr/bin:/path/to/something/else
    1 2 * * * command 
    

Komutunuz başka ortam değişkenleri gerektiriyorsa, bunları crontab dosyasında da tanımlayabilirsiniz.

cron komutunuzu cwd == $ HOME ile çalıştırır

Yürüttüğünüz programın dosya sisteminde nerede olduğuna bakılmaksızın, cron çalıştırıldığında programın geçerli çalışma dizini kullanıcının ana dizini olacaktır. Programınızdaki dosyalara erişiyorsanız, göreli yollar kullanıyorsanız veya (tercihen) yalnızca her yerde tam nitelikli yollar kullandığınızda bunu dikkate almanız ve herkesi çok fazla karışıklıktan kurtarmanız gerekir.

Crontab'ımdaki son komut çalışmıyor

Cron genellikle komutların yeni bir satırla sonlandırılmasını gerektirir. Crontab'ınızı düzenleyin; son komutu içeren satırın sonuna gidin ve yeni bir satır ekleyin (enter tuşuna basın).

Crontab biçimini kontrol edin

/ Etc/crontab için kullanıcı crontab biçimli crontab'ı veya /etc/cron.d içindeki parçaları veya tam tersini kullanamazsınız. Kullanıcı biçimli bir crontab, bir satırın 6. konumunda bir kullanıcı adı içermezken, sistem biçimli bir crontab kullanıcı adını içerir ve komutu bu kullanıcı olarak çalıştırır.

/Etc/cron.{hourly,daily,weekly,monthly} içine bir dosya koydum ve çalışmıyor

  • Dosya adının bir uzantısı olmadığından emin olun bkz. run-parts
  • Dosyanın yürütme izinlerine sahip olduğundan emin olun.
  • Komut dosyanızı yürütürken sisteme ne kullanacağınızı söyleyin (ör. #!/bin/sh En üste koyun)

Cron tarihiyle ilgili hatalar

Tarihiniz yakın zamanda bir kullanıcı veya sistem güncellemesi, saat dilimi veya başka bir kişi tarafından değiştirilirse, crontab düzensiz davranmaya başlar ve bazen çalışmaz, bazen çalışmaz. Bu, crontab'ın zaman altından değiştiğinde "ne istersen yap" çabasıdır. "Dakika" alanı, saat değiştirildikten sonra etkin olmayacaktır. Bu senaryoda, sadece yıldız işaretleri kabul edilir. Cron'u yeniden başlatın ve internete bağlanmadan tekrar deneyin (böylece tarihin zaman sunucularından birine sıfırlama şansı yoktur).

Yüzde işaretleri, yine

Yüzde işaretleri hakkındaki tavsiyeyi vurgulamak için, cronun onlarla ne yaptığına bir örnek:

# cron entry
* * * * * cat >$HOME/cron.out%foo%bar%baz

3 satırı içeren ~/cron.out dosyasını oluşturur

foo
bar
baz

Bu, date komutu kullanıldığında özellikle müdahaleci olur. Yüzde işaretlerinden kaçtığınızdan emin olun

* * * * * /path/to/command --day "$(date "+\%Y\%m\%d")"
352
Eric Leschinski

Debian Linux ve türevinin (Ubuntu, Mint, vb.) Cron işlerinizin yürütülmesini engelleyebilecek bazı özellikleri vardır; özellikle /etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly} zorunlu :

  • köküne ait olmak
  • sadece kök tarafından yazılabilir
  • grup veya diğer kullanıcılar tarafından yazılamaz
  • bir ada sahip herhangi bir nokta olmadan '.' veya '-' ve '_' dışında başka bir özel karakter içermelidir.

Sonuncusu, şüpheli olmayan kullanıcıları düzenli olarak incitir; özellikle bu klasörlerden birinde whatever.sh, mycron.py, testfile.pl, vb. değil yürütülür.

Deneyimlerime göre, bu özel nokta Debian ve türevleri üzerinde idam edilmeyen bir cronjob için en sık neden olmuştur.

Görmek man cron gerekirse daha fazla ayrıntı için.

25
wazoox

Cronjobs'unuzun çalışması durursa, parolanızın süresinin dolmadığını kontrol edin., Bir kez sahip olduğundan, tüm cron işleri durur.
/var/log/messages kullanıcının kimlik doğrulamasıyla ilgili sorunları gösteren aşağıdakine benzer:

(username) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)

20
Munkeh72

Yaygın olmayan ve düzensiz programlar

Cron her şey çok basit bir zamanlayıcı olarak kabul edilir ve sözdizimi bir yöneticinin biraz daha nadir olmayan zamanlamaları formüle etmesine kolayca izin vermez.

Genel olarak "run command her 5 dakikada bir" olarak açıklanacak şu işi düşünün:

*/5 * * * * /path/to/your/command

karşı:

*/7 * * * * /path/to/your/command

ki her 7 dakikada bir her zamancommand çalıştırmaz .

Unutmayın ki / karakteri bir adımı tanıtmak için kullanılabilir, ancak bu adımlar bir serinin sonunu aşmaz; */7 dakikalardan her 7. dakikada bir eşleşen 0-59 yani 0,7,14,21,28,35,42,49,56 ancak bir saat ve sonraki saat arasında olacaktır gruplar arasında sadece 4 dakika , 00:56 yeni bir seri 01:00, 01:07 vb. (ve gruplar 01:03, 01:10, 01:17 vb.).


Bunun yerine ne yapmalı?

Birden çok toplu iş oluşturun

Tek bir cron işinden ziyade, istenen zamanlamayla sonuçlanan birden çok toplu iş oluşturun.

Örneğin, her 40 dakikada bir (00:00, 00:40, 01:20, 02:00 vb.) Bir parti çalıştırmak için, biri çift saatlerde iki kez çalışan, diğeri ise yalnızca tek saatlerde çalışan iki grup oluşturun:

# The following lines create a batch that runs every 40 minutes i.e.

# runs on   0:00, 0:40,        02:00, 02:40         04:00 etc to 22:40
0,40 */2 * * * /path/to/your/command

# runs on               01:20,               03:20,       etc to 23:20
20 1/2 * * * /path/to/your/command

# Combined: 0:00, 0:40, 01:20, 02:00, 02:40, 03:20, 04:00 etc.

Partilerinizi daha az çalıştırın

Toplu işinizi 7 dakikada bir çalıştırmak yerine, birden fazla toplu iş için ayrılması zor bir programdır, bunun yerine 10 dakikada bir çalıştırın.

Toplu işlerinizi daha sık başlatın (ancak birden fazla toplu işin aynı anda çalışmasını engelleyin)

Parti çalışma zamanları arttığı/dalgalandığı ve daha sonra gruplar, aynı partinin sonraki çalışmalarının aynı anda üst üste binmesini ve çalışmasını önlemek için biraz ek güvenlik payı ile programlandığından birçok garip program gelişir.

Bunun yerine, farklı düşünün ve önceki bir çalışma henüz bitmediğinde incelikle başarısız olacak, ancak aksi halde çalışacak bir cronjob oluşturun. Şuna bakın Soru-Cevap :

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job 

Bu,/usr/local/bin/frequent_cron_job önceki çalışması tamamlandığında hemen yeni bir çalıştırma başlatır.

Partilerinizi daha sık başlatın (ancak koşullar doğru olmadığında zarif bir şekilde çıkın)

Cron sözdizimi sınırlı olduğundan toplu işin kendisine (veya mevcut toplu işin etrafına bir sarmalayıcı komut dosyasına) daha karmaşık koşullar ve mantık yerleştirmeye karar verebilirsiniz. . Bu, en sevdiğiniz komut dosyası dillerinin gelişmiş özelliklerini kullanmanıza, kodunuza yorum yapmanıza ve crontab girdisinin kendisinde okunması zor yapıları engellemenize olanak tanır.

Bash'da seven-minute-job sonra şöyle bir şey gibi görünecektir:

#!/bin/bash
# seven-minute-job
# This batch will only run when 420 seconds (7 min) have passed
# since the file /tmp/lastrun was either created or updated

if [ ! -f /tmp/lastrun ] ; then
    touch /tmp/lastrun
fi

if [ $(( $(date +%s) - $(date -r /tmp/lastrun +%s) )) -lt 420 ] ; then
     # The minimum interval of 7 minutes between successive batches hasn't passed yet.
    exit 0
fi

####  Start running your actual batch job below

/path/to/your/command

#### actual batch job is done, now update the time stamp
date > /tmp/lastrun
#EOF

Daha sonra her dakika güvenle çalıştırmayı deneyebilirsiniz:

* * * * * /path/to/your/seven-minute-job

Farklı, ancak benzer bir sorun, bir partinin her ayın ilk Pazartesi günü (veya ikinci Çarşamba) çalışacak şekilde zamanlanmasıdır.st veya 7inci ve haftanın günü Pazartesi değil.

#!/bin/bash
# first-monday-of-the-month-Housekeeping-job

# exit if today is not a Monday (and prevent locale issues by using the day number) 
if [ $(date +%u) != 1 ] ; then
  exit 0
fi

# exit if today is not the first Monday
if [ $(date +%d) -gt 7 ] ; then
  exit 0
fi

####  Start running your actual batch job below

/path/to/your/command

#EOF

Daha sonra her Pazartesi çalıştırmak için güvenle (deneyebilirsiniz):

0 0 * * 1 /path/to/your/first-monday-of-the-month-Housekeeping-job

Cron kullanma

İhtiyaçlarınız karmaşıksa, karmaşık zamanlamaları (birden çok sunucuya dağıtılmış) çalıştırmak için tasarlanmış ve tetikleyicileri, iş bağımlılıklarını, hata işlemeyi, yeniden denemeleri ve yeniden izlemeyi vb. Destekleyen daha gelişmiş bir ürün kullanmayı düşünebilirsiniz. " iş zamanlaması ve/veya" iş yükü otomasyonu ".

14
HBruijn

PHP özgü

Cron işiniz varsa:

php /bla/bla/something.php >> /var/logs/somelog-for-stdout.log

Ve hatalar beklenirse, size gönderileceklerini, ancak yapmadıklarını - kontrol edin.

PHP varsayılan olarak STDOUT'a hata göndermiyor. @ bakın https://bugs.php.net/bug.php?id=22839

Bunu düzeltmek için cli`s php.ini dosyasına veya satırınıza (veya PHP için bash paketleyicinize) şunları ekleyin:

  • --define display_startup_errors = 1
  • --define display_errors = 'stderr'

1. ayar, hepsini STDERR'a yönlendirmek için 'Memory oops' ve 2nd - gibi ölümcüllere sahip olmanızı sağlar. Sadece iyi uyuduktan sonra, hepsi sadece oturum açmak yerine kökünüzün postasına gönderilecektir.

8
gaRex

Tamlığım için yanıtımı buraya ekleme ve potansiyel olarak yararlı başka bir kaynak ekleme:

cron kullanıcısının farklı bir $PATH sizden daha:

Kullanıcıların crontab girdileriyle sık karşılaştığı bir sorun, cron ürününün, oturum açmış bir kullanıcı olarak yaptığından farklı bir environment çalıştığını unutmalarıdır. Örneğin, bir kullanıcı $HOME dizinine gidin ve çalıştırmak için aşağıdaki komutu girer:

$ ./certbot ... 

Komut, komut satırından mükemmel çalışır. Kullanıcı daha sonra bu komutu crontab klasörüne ekler, ancak bunun çalışmadığını bulur:

*/10 * * * * ./certbot ....

Bu durumda başarısızlığın nedeni ./cron kullanıcısı için oturum açmış olan kullanıcıdan farklı bir konumdur. Yani, environment farklı! PATH environment ürününün bir parçasıdır ve cron kullanıcısı için genellikle farklıdır. Bu sorunu karmaşık hale getirmek, environment için cron öğesinin tüm * nix dağıtımları için aynı olmaması ve cron

Bu özel soruna basit bir çözüm, cron kullanıcısına crontab girişinde tam bir yol belirtimi vermektir:

0 22 * * * /path/to/certbot .....

cron kullanıcısının environment nedir?

Bazı durumlarda, sistemimizde environment için _ cron spesifikasyonunu bilmemiz gerekebilir (ya da merak ediyoruz). environment kullanıcısı için cron nedir ve bizimkinden farkı nedir? Dahası, environment başka bir cron kullanıcı - root için ... _ root kullanan environment kullanıcı cron nedir? Bunu öğrenmenin bir yolu, cron ürününden bize şunu söylemesini istemek:

  1. Ana dizininizde bir Kabuk komut dosyası oluşturun (~/) aşağıdaki gibi (veya seçtiğiniz düzenleyiciyle):
$ nano ~/envtst.sh
  1. Sisteminizi/kullanıcınızı ayarladıktan sonra düzenleyiciye aşağıdakileri girin:
#!/bin/sh 
/bin/echo "env report follows for user "$USER >> /home/you/envtst.sh.out 
/usr/bin/env >> /home/you/envtst.sh.out 
/bin/echo "env report for user "$USER" concluded" >> /home/you/envtst.sh.out
/bin/echo " " >> /home/you/envtst.sh.out
  1. Dosyayı kaydedin, düzenleyiciden çıkın ve dosya izinlerini yürütülebilir olarak ayarlayın.
$ chmod a+rx ~/envtst.sh
  1. Yeni oluşturduğunuz komut dosyasını çalıştırın ve çıktıyı /home/you/envtst.sh.out. Bu çıktı mevcut ortamınızı $USER olarak giriş yaptınız:
$ ./envtst.sh $$ cat /home/you/envtst.sh.out
  1. Düzenlemek için crontab öğenizi açın:
$ crontab -e -u root
  1. crontab cihazınızın altına aşağıdaki satırı girin:
* * * * *  /home/you/envtst.sh >> /home/you/envtst.sh.err 2>&1

CEVAP: Çıktı dosyası /home/you/envtst.sh.out, "kök cron kullanıcısı" için environment öğesinin bir listesini içerecektir. Bunu öğrendikten sonra, crontab girişinizi uygun şekilde ayarlayın.

crontab girişimde ihtiyacım olan programı belirleyemiyorum:

crontab için program girişi elbette man crontab ve bunu okumalısınız. Ancak man crontab ve programı anlamak iki farklı şeydir. Ve bir zamanlama belirtimindeki deneme yanılma çok sıkıcı olabilir. Neyse ki, yardımcı olabilecek bir kaynak var: crontab guru. . Program spesifikasyonunuzu girin, program düz İngilizce olarak açıklanacaktır.

Son olarak ve buradaki diğer yanıtlardan biriyle gereksiz olma riskiyle karşı karşıya kalacağınız tek bir crontab girişi ile sınırlı olduğunuzu düşünerek tuzağa düşmeyin. İhtiyacınız olan programı almak için ihtiyaç duyduğunuz sayıda crontab giriş kullanmakta serbestsiniz.

0
Seamus