it-swarm.com.de

Wie teste ich einen wöchentlichen Cron Job?

Ich habe ein #!/bin/bash Datei im cron.week Verzeichnis.

Gibt es eine Möglichkeit zu testen, ob es funktioniert? Ich kann nicht 1 Woche warten

Ich bin auf Debian 6 mit root

226
dynamic

Tun Sie einfach, was Cron tut, und führen Sie Folgendes als root aus:

run-parts -v /etc/cron.weekly

... oder die nächste, wenn die Fehlermeldung "Not a directory: -v" angezeigt wird:

run-parts /etc/cron.weekly -v

Möglichkeit -v druckt die Skriptnamen aus, bevor sie ausgeführt werden.

226
NNRooth

Ein bisschen jenseits des Rahmens Ihrer Frage ... aber hier ist, was ich tue.

Das "Wie teste ich einen Cron Job?" Die Frage ist eng verbunden mit "Wie teste ich Skripts, die in nicht interaktiven Kontexten ausgeführt werden, die von anderen Programmen gestartet wurden?" In cron ist der Auslöser eine Zeitbedingung, aber viele andere * nix-Funktionen starten Skripte oder Skriptfragmente auf nicht interaktive Weise, und häufig enthalten die Bedingungen, unter denen diese Skripte ausgeführt werden, etwas Unerwartetes und verursachen einen Fehler, bis die Fehler behoben sind.

Eine allgemeine Herangehensweise an dieses Problem ist hilfreich.

Eine meiner Lieblingstechniken ist die Verwendung eines Skripts namens ' crontest '. Der Befehl target wird in einer GNU screen-Sitzung innerhalb von cron gestartet, sodass Sie mit einem separaten Terminal anzeigen können, was los ist, mit dem Skript interagieren und sogar einen Debugger verwenden können.

Um dies einzurichten, würden Sie "alle Sterne" in Ihrem crontab-Eintrag verwenden und crontest als ersten Befehl in der Befehlszeile angeben, z.

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

Jetzt führt cron Ihren Befehl jede Minute aus, aber crontest stellt sicher, dass jeweils nur eine Instanz ausgeführt wird. Wenn die Ausführung des Befehls einige Zeit in Anspruch nimmt, können Sie ein "screen -x" zum Anhängen und Ausführen des Befehls ausführen. Wenn es sich bei dem Befehl um ein Skript handelt, können Sie oben einen "Lese" -Befehl einfügen, um ihn anzuhalten und auf den Abschluss des Bildschirmanhangs zu warten (drücken Sie nach dem Anhängen die Eingabetaste).

Wenn Ihr Befehl ein Bash-Skript ist, können Sie dies stattdessen tun:

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

Wenn Sie jetzt "screen -x" anhängen, sehen Sie sich einer interaktiven Bashdb-Sitzung gegenüber, und Sie können den Code schrittweise durchgehen, Variablen untersuchen usw.

#!/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="[email protected]"
screenBin=$(which screen 2>/dev/null)

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

function log {
    echo "[-stat-] [email protected]" >> $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="[email protected]"
                return 0
                ;;
            *)
                innerArgs="[email protected]"
                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 "[email protected]"

    log "crontest starting at $(date)"
    log "Raw command line: [email protected]"
    log "Inner args: [email protected]"
    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
81
Stabledog

Nachdem ich mit einigen Dingen in Cron rumgespielt hatte, die nicht sofort kompatibel waren, stellte ich fest, dass der folgende Ansatz für das Debuggen gut war:

crontab -e

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

Dadurch wird die Aufgabe einmal pro Minute ausgeführt und Sie können einfach in der /tmp/cron_debug_log.log Datei, um herauszufinden, was los ist.

Es ist nicht genau der "Feuer-Job", nach dem Sie suchen, aber das hat mir beim Debuggen eines Skripts sehr geholfen, das zuerst in Cron nicht funktioniert hat.

40
Automatico

Ich würde eine Sperrdatei verwenden und dann den Cron-Job so einstellen, dass er jede Minute ausgeführt wird. (Verwenden Sie crontab -e und * * * * */path/to/job) Auf diese Weise können Sie die Dateien einfach weiter bearbeiten und jede Minute werden sie getestet. Darüber hinaus können Sie den Cronjob stoppen, indem Sie einfach die Sperrdatei berühren.

    #!/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
24
dave fernholz

Was ist mit dem Einfügen in cron.hourly, warten Sie bis zur nächsten Ausführung von Cron-Jobs pro Stunde und entfernen Sie sie dann? Das würde es einmal innerhalb einer Stunde und in der Cron-Umgebung ausführen. Sie können auch ./your_script, aber das hat nicht die gleiche Umgebung wie unter Cron.

5

Daneben können Sie auch verwenden:

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

zum Einpacken Ihres Cron, um Ihnen bei Erfolg oder Misserfolg eine E-Mail zu senden.

4
Low Kian Seong

Keine dieser Antworten passte zu meiner spezifischen Situation, dh, ich wollte einen bestimmten Cron-Job nur einmal ausführen und sofort ausführen.

Ich bin auf einem Ubuntu-Server und verwende cPanel, um meine Cron-Jobs einzurichten.

Ich habe einfach meine aktuellen Einstellungen aufgeschrieben und sie in einer Minute bearbeitet. Als ich einen weiteren Fehler behoben habe, habe ich ihn in einer Minute erneut bearbeitet. Und als ich fertig war, habe ich einfach die Einstellungen auf die vorherigen zurückgesetzt.

Beispiel: Es ist jetzt 16:34 Uhr, also habe ich 35 16 * * * eingegeben, damit es um 16:35 Uhr ausgeführt wird.

Es funktionierte wie ein Zauber und das meiste, auf das ich jemals warten musste, war etwas weniger als eine Minute.

Ich dachte, dies sei eine bessere Option als einige der anderen Antworten, da ich nicht alle meine wöchentlichen Cron ausführen wollte und nicht wollte, dass der Job jede Minute ausgeführt wird. Ich brauche ein paar Minuten, um die Probleme zu beheben, bevor ich bereit bin, sie erneut zu testen. Hoffentlich hilft das jemandem.

4
Ben C

Normalerweise teste ich durch Ausführen des Jobs, den ich so erstellt habe:

Es ist einfacher, dazu zwei Terminals zu verwenden.

auftrag ausführen:

#./jobname.sh

gehe zu:

#/var/log and run 

führen Sie Folgendes aus:

#tailf /var/log/cron

Dadurch kann ich die Aktualisierung der Cron-Protokolle in Echtzeit sehen. Sie können das Protokoll auch überprüfen, nachdem Sie es ausgeführt haben. Ich bevorzuge es, es in Echtzeit anzusehen.

Hier ist ein Beispiel eines einfachen Cron-Jobs. Ein Yum-Update ausführen ...

#!/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

Hier ist die Aufteilung:

Der erste Befehl aktualisiert yum selbst und der nächste Befehl führt Systemaktualisierungen durch.

-R 120: Legt die maximale Wartezeit für einen Befehl fest

-e 0: Setzt die Fehlerstufe auf 0 (Bereich 0 - 10). 0 bedeutet, dass nur kritische Fehler gedruckt werden, über die Sie informiert werden müssen.

-d 0: Setzt die Debugstufe auf 0 - dreht die Anzahl der gedruckten Objekte auf oder ab. (Bereich: 0 - 10).

-y: Angenommen, ja; Angenommen, die Antwort auf jede Frage wäre ja

Nachdem ich den Cron-Job erstellt habe, habe ich den folgenden Befehl ausgeführt, um meinen Job ausführbar zu machen.

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

Hoffe das hilft, Dorlack

2
Dorlack
Sudo run-parts --test /var/spool/cron/crontabs/

dateien in diesem crontabs/ Verzeichnis muss vom Eigentümer ausführbar sein - oktal 700

quelle: man cron und NNRooth

2
n611x007

Die Lösung, die ich benutze, ist wie folgt:

  1. Bearbeiten Sie crontab (verwenden Sie den Befehl crontab -e), um den Job so oft wie nötig auszuführen (alle 1 Minute oder 5 Minuten).
  2. Ändern Sie das Shell-Skript, das mit cron ausgeführt werden soll, um die Ausgabe in eine Datei zu drucken (z. B .: Echo "Gut funktionierend" >>)
    output.txt)
  3. Überprüfen Sie die Datei output.txt mit dem Befehl: tail -f output.txt, der die neuesten Ergänzungen in diese Datei druckt. Auf diese Weise können Sie die Ausführung des Skripts verfolgen
2
Abhilash