Haftalık bir cron işini test et [kapalı]


237

#!/bin/bashCron.week dizininde bir dosya var .

Çalışıp çalışmadığını test etmenin bir yolu var mı? 1 hafta bekleyemiyorum

Debian 6 ile rootluyum


4
Komut dosyasını komut satırında çalıştırarak test edemez misiniz?
Frédéric Hamidi

5
crontabbirkaç dakikada bir dosyanızı çalıştıran ayrı bir giriş ekleyin , beklenen sonuçların orada olup olmadığına bakın ve ardından test girişini crontab'ınızdan silin. deneyincrontab -e
davin

61
Hayır, komut satırından çalıştırmak iyi bir yol değildir. Komut dosyasını komut satırından çalıştırmak, aynı kullanıcının cron'dan çalıştırıldığında olduğu gibi çalışacağını garanti etmez. Aynı kullanıcı olarak çalıştırılsa bile, diğer her şeyin aynı olup olmayacağından asla emin olamazsınız. Komut satırından çalışan komut dosyaları, cron'dan çalıştırıldığında her türlü nedenden dolayı başarısız olabilir .
andynormancx

8
"her türlü" biraz hiperbolik olabilir ... izinler ve ortam değişkenleri akla ilk gelen iki, yine de takma adlar gibi farklı başlangıç ​​koşullarına kolayca sahip olabilirsiniz
andynormancx

3
Yeni bir cron işini test ettim, "her türlü" e başka bir öğe ekleyeceğim. Eğer bash_profile içinde bir şey varsa, bir cron işinde bir kez çalıştırılmazlar, oysa işi komut satırından test etmek mükemmel çalışır. Standart komut satırında cron işlerini test etmek hiç de iyi bir test değildir.
andynormancx

Yanıtlar:


233

Sadece cron'un yaptığı şeyi yapın, aşağıdakileri çalıştırın root:

run-parts -v /etc/cron.weekly

... veya "Dizin değil: -v" hatasını alırsanız bir sonraki:

run-parts /etc/cron.weekly -v

Seçenek -v, komut dosyası adlarını çalıştırmadan önce yazdırır.


4
-V seçeneğini "Dizin değil: -v" hatası gösteriyorsa, sistemimde bu komut için bir man sayfası yok, -v ayrıntılı değil mi? Centos kullanıyorum 6.4
max

3
"Bir dizin değil" hatasını önlemek için, bunun yerine bunu yapmak zorunda kaldım: run-parts /etc/cron.weekly -v
Craig Hyatt

22
Ancak bu, crontab'da ayarlanabilecek ortam değişkenlerini hesaba
katmaz

34
run-partssadece belirli bir dizinin komut dosyalarını çalıştırır. Cron ile ilgisi yok.
Nicolas

23
Bu gerçekten değerlendirilmemeli ve kabul edilmemeliydi, betiği çalıştırmanın ötesinde, bronun cron'dan çalıştırıldığında gerçekten işe yarayıp yaramayacağını söylemek için hiçbir şey yapmaz. Bu sorunun diğer cevaplarından birinde mükemmel crontest komut dosyasını kullanın.
andynormancx

87

Sorunuzun kapsamının biraz ötesinde ... ama işte buradayım.

"Bir cron işini nasıl test ederim?" sorusu, "diğer programlar tarafından başlatılan etkileşimli olmayan bağlamlarda çalışan komut dosyalarını nasıl test edebilirim?" Cron'da tetikleyici bir zaman koşuludur, ancak diğer birçok * nix özelliği komut dosyalarını veya komut dosyası parçalarını etkileşimli olmayan yollarla başlatır ve genellikle bu komut dosyalarının çalıştığı koşullar beklenmedik bir şey içerir ve hatalar çözülene kadar kırılmaya neden olur. (Ayrıca bkz: https://stackoverflow.com/a/17805088/237059 )

Bu soruna genel bir yaklaşımın olması faydalıdır.

En sevdiğim tekniklerden biri, ' crontest ' adlı bir senaryo kullanmak . Hedef komutu, bir GNU ekran oturumunda cron içinden başlatır, böylece neler olduğunu görmek, komut dosyası ile etkileşime girmek, hatta bir hata ayıklayıcı kullanmak için ayrı bir terminal ekleyebilirsiniz.

Bunu ayarlamak için, crontab girişinizde "all stars" kullanırsınız ve komut satırında ilk komut olarak crontest'i belirtirsiniz, örneğin:

* * * * * crontest /command/to/be/tested --param1 --param2

Şimdi cron komutunuzu her dakika çalıştıracak, ancak crontest her seferinde sadece bir örneğin çalışmasını sağlayacaktır. Komutun çalışması zaman alıyorsa, eklemek ve çalışmasını izlemek için bir "screen -x" yapabilirsiniz. Komut bir komut dosyasıysa, durdurmak için ekranın üst kısmına "okuma" komutu koyabilir ve ekran ekinin tamamlanmasını bekleyebilirsiniz (ekledikten sonra enter tuşuna basın)

Komutunuz bir bash betiğiyse, bunun yerine bunu yapabilirsiniz:

* * * * * crontest --bashdb /command/to/be/tested --param1 --param2

Şimdi, "screen -x" ile eklerseniz, etkileşimli bir bashdb oturumuyla karşı karşıya kalırsınız ve kod içinde adım atabilir, değişkenleri inceleyebilirsiniz, vb.

#!/bin/bash

# crontest
# See https://github.com/Stabledog/crontest for canonical source.

# Test wrapper for cron tasks.  The suggested use is:
#
#  1. When adding your cron job, use all 5 stars to make it run every minute
#  2. Wrap the command in crontest
#        
#
#  Example:
#
#  $ crontab -e
#     * * * * * /usr/local/bin/crontest $HOME/bin/my-new-script --myparams
#
#  Now, cron will run your job every minute, but crontest will only allow one
#  instance to run at a time.  
#
#  crontest always wraps the command in "screen -d -m" if possible, so you can
#  use "screen -x" to attach and interact with the job.   
#
#  If --bashdb is used, the command line will be passed to bashdb.  Thus you
#  can attach with "screen -x" and debug the remaining command in context.
#
#  NOTES:
#   - crontest can be used in other contexts, it doesn't have to be a cron job.
#       Any place where commands are invoked without an interactive terminal and
#       may need to be debugged.
#
#   - crontest writes its own stuff to /tmp/crontest.log
#
#   - If GNU screen isn't available, neither is --bashdb
#

crontestLog=/tmp/crontest.log
lockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )
useBashdb=false
useScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )
innerArgs="$@"
screenBin=$(which screen 2>/dev/null)

function errExit {
    echo "[-err-] $@" | tee -a $crontestLog >&2
}

function log {
    echo "[-stat-] $@" >> $crontestLog
}

function parseArgs {
    while [[ ! -z $1 ]]; do
        case $1 in
            --bashdb)
                if ! $useScreen; then
                    errExit "--bashdb invalid in crontest because GNU screen not installed"
                fi
                if ! which bashdb &>/dev/null; then
                    errExit "--bashdb invalid in crontest: no bashdb on the PATH"
                fi

                useBashdb=true
                ;;
            --)
                shift
                innerArgs="$@"
                return 0
                ;;
            *)
                innerArgs="$@"
                return 0
                ;;
        esac
        shift
    done
}

if [[ -z  $sourceMe ]]; then
    # Lock the lockfile (no, we do not wish to follow the standard
    # advice of wrapping this in a subshell!)
    exec 9>$lockfile
    flock -n 9 || exit 1

    # Zap any old log data:
    [[ -f $crontestLog ]] && rm -f $crontestLog

    parseArgs "$@"

    log "crontest starting at $(date)"
    log "Raw command line: $@"
    log "Inner args: $@"
    log "screenBin: $screenBin"
    log "useBashdb: $( if $useBashdb; then echo YES; else echo no; fi )"
    log "useScreen: $( if $useScreen; then echo YES; else echo no; fi )"

    # Were building a command line.
    cmdline=""

    # If screen is available, put the task inside a pseudo-terminal
    # owned by screen.  That allows the developer to do a "screen -x" to
    # interact with the running command:
    if $useScreen; then
        cmdline="$screenBin -D -m "
    fi

    # If bashdb is installed and --bashdb is specified on the command line,
    # pass the command to bashdb.  This allows the developer to do a "screen -x" to
    # interactively debug a bash shell script:
    if $useBashdb; then
        cmdline="$cmdline $(which bashdb) "
    fi

    # Finally, append the target command and params:
    cmdline="$cmdline $innerArgs"

    log "cmdline: $cmdline"


    # And run the whole schlock:
    $cmdline 

    res=$?

    log "Command result: $res"


    echo "[-result-] $(if [[ $res -eq 0 ]]; then echo ok; else echo fail; fi)" >> $crontestLog

    # Release the lock:
    9<&-
fi

2
Harika, mükemmel çözüm. Denediğim diğer tüm teknikler gerçekten işe yaramadı, crontest sorunu kolayca çözdü.
andynormancx

1
Bu ihtiyacımdan çok daha fazla oldu ama yine de harika bir çözüm için +1; daha sık çalıştırmak ve çıkış / tmp dökümü ayarlamak cron benim sorun tespit etmek için iyi oldu.
jcollum

2
Güzel. Evet, sadece bir kürek gerekiyorsa buldozer ateşlemek için bir neden yok :)
Stabledog

2
Harika şeyler. Mac hakkında not brew tap discoteq/discoteq; brew install flockve daha sonra kullanmak için komut dosyasını değiştirmek zorunda/usr/local/bin/flock
Claudiu

1
güzel yarar! Etkileşimli olmayan bağlamlarda kimlik doğrulama sorunlarını tanılamak için çok yararlıdır.
Eric Blum

44

Anında uyumlu olmayan cron'daki bazı şeylerle uğraştıktan sonra, aşağıdaki yaklaşımın hata ayıklama için güzel olduğunu gördüm:

crontab -e

* * * * * /path/to/prog var1 var2 &>>/tmp/cron_debug_log.log

Bu, görevi dakikada bir kez çalıştırır ve /tmp/cron_debug_log.logneler olduğunu anlamak için dosyaya bakabilirsiniz .

Tam olarak aradığınız "ateş işi" değil, ama bu ilk başta cron'da çalışmayan bir senaryoda hata ayıklarken bana çok yardımcı oldu.


9
Bu yaklaşımı tavsiye ederim. Çoğu durumda sorun, hatayı görmemenizdir.
Yauhen Yakimovich

8
Yanlış çizgi, herhangi bir dağıtım cron kabuğu için bash kullanmaz ve bu nedenle & >> çalışmaz. >>/tmp/cron_debug_log.log 2>&1Bunun yerine kullanmanızı öneririm
18'de drizzt

1
Ne demek istiyorsun /path/to/prog- hangi prog?
Nathan

3
Cron ile çalıştıracağınız program. Bu olabilir usr/home/myFancyScript.shveya basit olabilir lsveya düzenli olarak çalıştırmak istediğiniz her şey olabilir.
Automatico

Bu benim için çalıştı. Her şeyin yolunda olup olmadığını kontrol etmek için hızlı bir test yapmak en kolay yöntemdi
abhijit

25

Bir kilit dosyası kullanır ve daha sonra cron işini her dakika çalışacak şekilde ayarlarım. (crontab -e ve * * * * * / path / to / job dizinlerini kullanın) Bu şekilde dosyaları düzenlemeye devam edebilirsiniz ve her dakika test edilir. Ek olarak, cronjob'u sadece kilit dosyasına dokunarak durdurabilirsiniz.

    #!/bin/sh
    if [ -e /tmp/cronlock ]
    then
        echo "cronjob locked"
        exit 1
    fi

    touch /tmp/cronlock
    <...do your regular cron here ....>
    rm -f /tmp/cronlock

4
Kabuktan da kullanabilirsiniz flock(1); bakın man 1 flock. Otomatik engelleme sağladığı için bu tür kullanımlar için oldukça kullanışlıdır.
Craig Ringer

5

Onu yerleştirmeye cron.hourly, bir sonraki saatlik cron işlerine kadar beklemeye ve sonra çıkarmaya ne dersiniz ? Bu bir saat içinde bir kez ve cron ortamında çalıştıracaktır. Ayrıca koşabilirsiniz ./your_script, ancak bu cron altındaki ortamla aynı olmaz.


Bu, daha az ayrıntıyla @ Cort3z'in cevabı ile hemen hemen aynı
jcollum

5

Bu cevapların hiçbiri benim özel durumuma uymuyor, bu yüzden sadece bir kez belirli bir cron işi yapmak ve hemen çalıştırmak istedim.

Bir Ubuntu sunucusuyum ve cron işlerimi ayarlamak için cPanel kullanıyorum.

Geçerli ayarlarımı yazdım ve sonra bir dakika olacak şekilde düzenledim. Başka bir hatayı düzelttiğimde, bir dakika sonra tekrar düzenledim. Ve işim bittiğinde, ayarları daha önce olduğu gibi sıfırladım.

Örnek: Şu anda 16:34 pm, bu yüzden 16:35'te çalışması için 35 16 * * * koydum.

Bir cazibe gibi çalıştı ve şimdiye kadar beklemek zorunda kaldı bir dakikadan biraz daha az oldu.

Bunun diğer cevaplardan daha iyi bir seçenek olduğunu düşündüm, çünkü tüm haftalık cronslarımı çalıştırmak istemedim ve işin her dakika çalışmasını istemedim. Tekrar test etmeye hazır olmadan önce sorunların ne olduğunu düzeltmem birkaç dakika sürüyor. Umarım bu birine yardımcı olur.


Neden sadece bir kez çalıştırmak ve hemen çalıştırmak için cron'u kullanasınız ki? Sadece betiği doğrudan çalıştırmak daha iyi olur gibi görünüyor.
Ian Hunter

4

Bunun dışında şunları da kullanabilirsiniz:

http://pypi.python.org/pypi/cronwrap

başarı veya başarısızlık durumunda size bir e-posta göndermek için cron'unuzu tamamlayın.


10
Cron yürütüldükten sonra koddan e-posta ve çıktı almıyor mu?
Erik

Cron kullanıcıya e-posta gönderir ve çoğu cron işi için kullanıcı kök veya etkileşimli olmayan bir hizmet kullanıcısıdır, bu nedenle e-postaları asla görmezsiniz. Bir hata büyük bir e-posta selini tetiklediğinde ve kökünden sektiğinde sunucular bu şekilde doldurulur.
dragon788

3

Kullandığım çözüm aşağıdaki gibidir:

  1. İşi gerektiği sıklıkta (1 dakikada veya 5 dakikada bir) çalıştırmak için crontab'ı düzenleyin (command: crontab -e) kullanın
  2. Çıkışı bir dosyaya yazdırmak için cron kullanılarak yürütülmesi gereken kabuk betiğini değiştirin (örn: echo "Working fine" >>
    output.txt)
  3. Bu dosyaya en son eklemeleri yazdıracak kuyruk: f output.txt komutunu kullanarak output.txt dosyasını kontrol edin ve betiğin çalışmasını takip edebilirsiniz.

2

Normalde böyle oluşturduğum işi çalıştırarak test ederim:

Bunu yapmak için iki terminal kullanmak daha kolaydır.

işi yap:

#./jobname.sh

git:

#/var/log and run 

aşağıdakileri çalıştırın:

#tailf /var/log/cron

Bu, cron günlüklerinin güncellemesini gerçek zamanlı olarak görmemi sağlıyor. Günlüğü çalıştırdıktan sonra da inceleyebilirsiniz, gerçek zamanlı izlemeyi tercih ederim.

İşte basit bir cron işi örneği. Yum güncellemesi çalıştırılıyor ...

#!/bin/bash
YUM=/usr/bin/yum
$YUM -y -R 120 -d 0 -e 0 update yum
$YUM -y -R 10 -e 0 -d 0 update

İşte arıza:

İlk komut yum'un kendisini güncelleyecek ve daha sonra sistem güncellemelerini uygulayacak.

-R 120: Bir komut gerçekleştirmeden önce yum'un bekleyeceği maksimum süreyi ayarlar

-e 0: Hata seviyesini 0 (aralık 0-10) olarak ayarlar. 0, yalnızca size söylenmesi gereken kritik hataları yazdırmak anlamına gelir.

-d 0: Hata ayıklama düzeyini 0 olarak ayarlar - yazdırılan öğelerin miktarını artırır veya azaltır. (aralık: 0 - 10).

-y: Evet diyelim; varsayalım ki herhangi bir sorunun cevabının evet olduğunu varsayalım

Cron işini yaptıktan sonra işimi yürütülebilir hale getirmek için aşağıdaki komutu çalıştırdım.

#chmod +x /etc/cron.daily/jobname.sh 

Umarım bu yardımcı olur, Dorlack


2
sudo run-parts --test /var/spool/cron/crontabs/

dizindeki dosyaların sahibi tarafından yürütülebilircrontabs/ olması gerekir - octal700

kaynak: man cronand NNRooth's


5
İki renk. İlk olarak: şeyleri sudo olarak çalıştırmak farklı bir ortam kullanır (tanımlı değişkenler). Bu nedenle crontab'ınızdaki hatalar 'sudo' olarak yürütüldüğünde çalışabilir, ancak 'root' olarak yürütüldüğünde çalışmayacaktır (ve tersi de geçerlidir). İkincisi: 'man cron' bana bu bilgiyi göstermiyor (tamam, adamım debian'a özgü görünüyor) ... 'man run-parts' diyor ki --test komut dosyalarını çalıştırmaz, sadece isimlerini yazdırır onlar. Yani senaryolar test edilmedi bile. Küçük bir şey: 'sahibi tarafından yürütülebilir': Bildiğim kadarıyla, cronjobs sadece kök olarak yürütülür.
Alex

-1

Webmin kullanıyorum çünkü onun komut satırı yönetimini biraz zor ve delinmez bulan bir verimlilik taşıdır.

"Sistem> Zamanlanmış Cron İşleri> Cron İşini Düzenle" web arayüzünde bir "Şimdi Kaydet ve Çalıştır" düğmesi var.

Komutun çıktısını görüntüler ve tam olarak ihtiyacım olan şey.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.