Testen Sie einen wöchentlichen Cron-Job [geschlossen]


237

Ich habe eine #!/bin/bashDatei im Verzeichnis cron.week.

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

Ich bin auf Debian 6 mit root


4
Können Sie das Skript nicht einfach testen, indem Sie es in der Befehlszeile ausführen?
Frédéric Hamidi

5
Fügen Sie einfach einen separaten Eintrag in Ihren hinzu crontab, der Ihre Datei alle paar Minuten ausführt, prüfen Sie, ob die erwarteten Ergebnisse vorliegen, und löschen Sie dann den Testeintrag von Ihrer crontab. versuchencrontab -e
David

61
Nein, es ist kein guter Weg, es über die Befehlszeile auszuführen. Das Ausführen des Skripts über die Befehlszeile garantiert nicht, dass es sogar so ausgeführt wird, wie es derselbe Benutzer war, als er von cron ausgeführt wurde. Selbst wenn es als derselbe Benutzer ausgeführt wird, können Sie nie sicher sein, ob alles andere gleich ist. Skripte , die Arbeit von der Kommandozeile kann nicht alle Arten von Gründen , wenn sie von cron.
Andynormancx

8
"alle Arten" können leicht hyperbolisch sein ... Berechtigungen und Umgebungsvariablen sind die beiden, die mir in den Sinn kommen. Sie könnten jedoch leicht andere Anfangsbedingungen wie Aliase haben
andynormancx

3
Ich habe gerade einen neuen Cron-Job getestet und werde "alle möglichen" einen weiteren Artikel hinzufügen. Wenn Sie Dinge in bash_profile haben, werden sie in einem Cron-Job nicht einmal ausgeführt, während das Testen des Jobs über die Befehlszeile einwandfrei funktioniert. Das Testen von Cron-Jobs über die Standardbefehlszeile ist überhaupt kein guter Test.
andynormancx

Antworten:


233

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

run-parts -v /etc/cron.weekly

... oder der nächste, wenn Sie den Fehler "Kein Verzeichnis: -v" erhalten:

run-parts /etc/cron.weekly -v

Option -vdruckt die Skriptnamen, bevor sie ausgeführt werden.


4
Wenn ich die Option -v verwende, die den Fehler "Kein Verzeichnis: -v" anzeigt, gibt es in meinem System keine Manpage für diesen Befehl. -V bedeutet ausführlich, oder? Ich benutze Centos 6.4
max

3
Um den Fehler "Kein Verzeichnis" zu vermeiden, musste ich stattdessen Folgendes tun: run-parts /etc/cron.weekly -v
Craig Hyatt

22
Dies berücksichtigt jedoch nicht die Umgebungsvariablen, die in der crontab
fcurella

34
run-partsführt nur die Skripte eines bestimmten Verzeichnisses aus. Nichts mit Cron zu tun.
Nicolas

23
Dies hätte wirklich nicht positiv bewertet und akzeptiert werden dürfen. Über das Ausführen des Skripts hinaus gibt es keinen Hinweis darauf, ob das Skript tatsächlich funktioniert, wenn es von cron ausgeführt wird. Verwenden Sie das ausgezeichnete Crontest-Skript in einer der anderen Antworten auf diese Frage.
andynormancx

87

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 Skripte, die in nicht interaktiven Kontexten ausgeführt werden, die von anderen Programmen gestartet wurden?" In cron ist der Auslöser eine zeitliche Bedingung, 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 Bruch, bis die Fehler behoben sind. (Siehe auch: https://stackoverflow.com/a/17805088/237059 )

Ein allgemeiner Ansatz für dieses Problem ist hilfreich.

Eine meiner Lieblingstechniken ist die Verwendung eines von mir geschriebenen Skripts namens " Crontest ". Es startet den Zielbefehl innerhalb einer GNU-Bildschirmsitzung von cron aus, sodass Sie mit einem separaten Terminal anhängen können, um zu sehen, 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 einen "Bildschirm -x" ausführen, um ihn anzuhängen und die Ausführung zu beobachten. 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 stattdessen Folgendes tun:

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

Wenn Sie jetzt mit "screen -x" anhängen, sehen Sie sich einer interaktiven Bashdb-Sitzung gegenüber, und Sie können den Code schrittweise durchlaufen, 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="$@"
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
Genial, die perfekte Lösung. Alle anderen Techniken, die ich ausprobiert hatte, funktionierten nicht wirklich. Crontest löste das Problem leicht.
andynormancx

1
Dies war weit mehr als ich brauchte, aber +1 für eine großartige Lösung; Es war gut genug, den Cron so einzustellen, dass er häufiger ausgeführt wird und die Ausgabe an / tmp ausgegeben wird, um mein Problem zu erkennen.
JCollum

2
Cool. Ja, kein Grund, den Bulldozer zu
starten,

2
Tolles Zeug. Hinweis auf Mac Ich musste brew tap discoteq/discoteq; brew install flockund dann das Skript ändern, um zu verwenden/usr/local/bin/flock
Claudiu

1
schönes Dienstprogramm! Sehr nützlich, um Authentifizierungsprobleme in nicht interaktiven Kontexten zu diagnostizieren.
Eric Blum

44

Nachdem ich mit einigen Dingen in Cron herumgespielt hatte, die nicht sofort kompatibel waren, stellte ich fest, dass der folgende Ansatz zum 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 die /tmp/cron_debug_log.logDatei schauen, um herauszufinden, was gerade passiert.

Es ist nicht genau der "Feuerjob", nach dem Sie vielleicht suchen, aber das hat mir sehr geholfen, als ich ein Skript debuggte, das anfangs nicht in cron funktionierte.


9
Ich würde diesen Ansatz empfehlen. Das Problem ist in den meisten Fällen, dass Sie den Fehler nicht sehen.
Yauhen Yakimovich

8
Falsche Zeile, keine Distribution verwendet Bash für Cron Shell und daher funktioniert & >> nicht. Ich schlage vor, >>/tmp/cron_debug_log.log 2>&1stattdessen zu verwenden
drizzt

1
Was meinst du mit /path/to/prog- welchem ​​Prog?
Nathan

3
Das Programm, das Sie mit cron ausführen werden. Dies kann usr/home/myFancyScript.shoder kann einfach sein lsoder was auch immer Sie regelmäßig ausführen möchten.
Automatico

Das hat bei mir funktioniert. Es war die einfachste Methode, einen Schnelltest durchzuführen, um zu überprüfen, ob alles in Ordnung ist
abhijit

25

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. Außerdem 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

4
Sie können auch flock(1)von der Shell verwenden; siehe man 1 flock. Sehr praktisch für solche Zwecke, da es eine automatische Blockierung bietet.
Craig Ringer

5

Wie wäre es cron.hourly, wenn Sie es einlegen , bis zum nächsten Durchlauf von Cron-Jobs warten und es dann entfernen? Das würde es einmal innerhalb einer Stunde und in der Cron-Umgebung ausführen. Sie können auch ausführen ./your_script, aber das hat nicht die gleiche Umgebung wie unter cron.


Dies ist so ziemlich das Gleiche wie die Antwort von @ Cort3z, mit weniger Details
jcollum

5

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

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

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

Beispiel: Es ist jetzt 16:34 Uhr, also habe ich 35 16 * * * gesetzt, damit es um 16:35 Uhr läuft.

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, weil ich nicht alle meine wöchentlichen Crones 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.


Warum sollten Sie cron verwenden, um "nur einmal und sofort" auszuführen? Es hört sich so an, als wären Sie besser dran, wenn Sie das Skript direkt ausführen.
Ian Hunter vor

4

Abgesehen davon können Sie auch verwenden:

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

um Ihren Cron einzupacken und Ihnen bei Erfolg oder Misserfolg eine E-Mail zu senden.


10
Versendet Cron nicht bereits bei der Ausführung eine E-Mail und eine Ausgabe aus dem Skript?
Erik

Cron sendet dem Benutzer eine E-Mail, und normalerweise ist der Benutzer für die meisten Cron-Jobs entweder ein Root- oder ein nicht interaktiver Dienstbenutzer, sodass Sie die E-Mails nie sehen. Auf diese Weise werden Server gefüllt, wenn ein Fehler eine große Flut von E-Mails auslöst und sie zu root springen.
Dragon788

3

Die Lösung, die ich verwende, lautet 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 "Working fine" >> 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, und verfolgen Sie so die Ausführung des Skripts

2

Normalerweise teste ich, indem ich den von mir erstellten Job wie folgt ausführe:

Es ist einfacher, zwei Terminals zu verwenden, um dies zu tun.

Job ausführen:

#./jobname.sh

gehe zu:

#/var/log and run 

Führen Sie Folgendes aus:

#tailf /var/log/cron

Auf diese Weise kann ich sehen, wie die Cron-Protokolle in Echtzeit aktualisiert werden. 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 für einen einfachen Cron-Job. Ein leckeres 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 Aufschlüsselung:

Der erste Befehl aktualisiert yum selbst und der nächste wendet Systemaktualisierungen an.

-R 120: Legt die maximale Wartezeit fest, bevor ein Befehl ausgeführt wird

-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 Debugging-Stufe auf 0 - Erhöht oder verringert die Anzahl der gedruckten Elemente. (Bereich: 0 - 10).

-y: Angenommen, ja; Angenommen, die Antwort auf jede gestellte Frage lautet Ja

Nachdem ich den Cron-Job erstellt hatte, führte ich den folgenden Befehl aus, um meinen Job ausführbar zu machen.

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

Hoffe das hilft, Dorlack


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

Dateien in diesem crontabs/Verzeichnis müssen vom Eigentümer - oktal ausführbar sein700

Quelle: man cronund NNRooth's


5
Zwei Töne. Erstens: Um sudo auszuführen, wird eine andere Umgebung verwendet (definierte Variablen). Fehler in Ihrer Crontab könnten also funktionieren, wenn sie als "sudo" ausgeführt werden, aber nicht, wenn sie als "root" ausgeführt werden (und umgekehrt). Zweitens: 'man cron' zeigt mir diese Informationen nicht an (ok, mein Mann scheint debian-spezifisch zu sein) ... 'man run-parts' sagt, dass --test die Skripte nicht ausführt, sondern nur die Namen von druckt Sie. Die Skripte werden also nicht einmal getestet. Eine Kleinigkeit: 'Vom Eigentümer ausführbar': Soweit ich weiß, werden Cronjobs nur als Root ausgeführt.
Alex

-1

Ich verwende Webmin, weil es ein Produktivitätsjuwel für jemanden ist, der die Befehlszeilenverwaltung als etwas entmutigend und undurchdringlich empfindet.

In der Weboberfläche "System> Geplante Cron-Jobs> Cron-Job bearbeiten" befindet sich die Schaltfläche "Jetzt speichern und ausführen".

Es zeigt die Ausgabe des Befehls an und ist genau das, was ich brauchte.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.