web-dev-qa-db-fra.com

Comment tester un travail hebdomadaire?

J'ai un fichier #!/bin/bash dans le répertoire cron.week.

Y a-t-il un moyen de tester si cela fonctionne? Je ne peux pas attendre 1 semaine

Je suis sur Debian 6 avec la racine

226
dynamic

Faites ce que cron fait, lancez ce qui suit en tant que root:

run-parts -v /etc/cron.weekly

... ou le suivant si vous recevez l'erreur "Not a directory: -v":

run-parts /etc/cron.weekly -v

L'option -v imprime les noms de script avant leur exécution.

226
NNRooth

Un petit peu au-delà de la portée de votre question ... mais voici ce que je fais.

Le "comment puis-je tester un travail cron?" question est étroitement liée à "comment tester des scripts exécutés dans des contextes non interactifs lancés par d'autres programmes?" Dans cron, le déclencheur est une condition de temps, mais de nombreuses autres installations * nix lancent des scripts ou des fragments de script de manière non interactive, et souvent les conditions dans lesquelles ces scripts s'exécutent contiennent quelque chose d'inattendu et causent des problèmes jusqu'à la résolution des bogues.

Une approche générale de ce problème est utile.

Une de mes techniques préférées consiste à utiliser un script que j'ai écrit et qui s'appelle ' crontest '. Il lance la commande target dans une session écran GNU à partir de cron, de sorte que vous puissiez vous connecter à un terminal distinct pour voir ce qui se passe, interagir avec le script, voire utiliser un débogueur.

Pour configurer ceci, vous utiliseriez "toutes les étoiles" dans votre entrée de crontab, et spécifiez crontest comme première commande de la ligne de commande, par exemple:

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

Alors maintenant, cron exécutera votre commande toutes les minutes, mais crontest garantira qu'une seule instance est exécutée à la fois. Si l'exécution de la commande prend du temps, vous pouvez créer un "écran -x" pour l'attacher et le regarder courir. Si la commande est un script, vous pouvez placer une commande "lire" en haut pour l'arrêter et attendre la fin de la pièce jointe à l'écran (appuyez sur Entrée après l'attachement)

Si votre commande est un script bash, vous pouvez le faire à la place:

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

Maintenant, si vous attachez avec "screen -x", vous ferez face à une session interactive bashdb, et vous pourrez parcourir le code, examiner les variables, etc.

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

Après avoir jeté un œil sur certains éléments de cron qui n'étaient pas immédiatement compatibles, j'ai trouvé que l'approche suivante était agréable pour le débogage:

crontab -e

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

Cela exécutera la tâche une fois par minute et vous pourrez simplement regarder dans le fichier /tmp/cron_debug_log.log pour comprendre ce qui se passe.

Ce n'est pas exactement le "job de feu" que vous recherchez, mais cela m'a beaucoup aidé lors du débogage d'un script qui ne fonctionnait pas dans cron au début.

40
Automatico

J'utilisais un fichier de verrouillage, puis je configurais le travail cron pour qu'il s'exécute toutes les minutes. (utilisez crontab -e et * * * * */path/to/job). Ainsi, vous pourrez continuer à éditer les fichiers et à chaque minute, ils seront testés. De plus, vous pouvez arrêter le travail cron en touchant simplement le fichier de verrouillage.

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

Qu'en est-il de le placer dans cron.hourly, d'attendre la prochaine exécution de tâches cron horaires, puis de le supprimer? Cela fonctionnerait une fois en une heure et dans l'environnement cron. Vous pouvez également exécuter ./your_script, mais cela n'aura pas le même environnement que sous cron.

5
Jeremiah Willcock

En plus de cela, vous pouvez également utiliser:

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

pour envelopper votre cron pour vous envoyer un email en cas de succès ou d’échec.

4
Low Kian Seong

Aucune de ces réponses ne correspond à ma situation spécifique, à savoir que je souhaitais exécuter un travail cron spécifique, juste une fois, et l'exécuter immédiatement.

Je suis sur un serveur Ubuntu et j'utilise cPanel pour configurer mes tâches cron.

J'ai simplement noté mes paramètres actuels, puis les ai modifiés pour qu'ils soient dans une minute. Quand j'ai corrigé un autre bogue, je l'ai simplement édité à nouveau dans une minute. Et quand tout était fini, je venais de réinitialiser les paramètres tels qu'ils étaient auparavant.

Exemple: Il est 16h34, je mets donc 35 16 * * *, pour qu’il fonctionne à 16h35.

Cela a fonctionné comme un charme, et le plus que j'ai dû attendre était un peu moins d'une minute.

Je pensais que c'était une meilleure option que certaines des autres réponses parce que je ne voulais pas exécuter tous mes cours hebdomadaires, et je ne voulais pas que le travail soit exécuté à la minute. Il me faut quelques minutes pour résoudre tous les problèmes avant de pouvoir le tester à nouveau. Espérons que cela aide quelqu'un.

4
Ben C

Je teste normalement en exécutant le travail que j'ai créé comme ceci:

Pour ce faire, il est plus facile d’utiliser deux terminaux.

exécuter le travail:

#./jobname.sh

aller à:

#/var/log and run 

lancez ce qui suit:

#tailf /var/log/cron

Cela me permet de voir la mise à jour des journaux cron en temps réel. Vous pouvez également consulter le journal après l'avoir exécuté. Je préfère regarder en temps réel.

Voici un exemple de travail cron simple. Lancer une mise à jour miam ...

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

Voici la ventilation:

La première commande mettra à jour yum et appliquera ensuite les mises à jour du système.

-R 120: définit le délai maximum d'attente de yum avant l'exécution d'une commande.

-e 0: définit le niveau d'erreur sur 0 (plage de 0 à 10). 0 signifie que seules les erreurs critiques dont vous devez être informé sont imprimées.

-d 0: définit le niveau de débogage sur 0 - augmente ou réduit le nombre d'éléments imprimés. (plage: 0 - 10).

-y: supposons que oui; supposons que la réponse à toute question qui serait posée est oui

Après avoir créé le travail cron, j'ai exécuté la commande ci-dessous pour rendre mon travail exécutable.

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

J'espère que cela vous aidera, Dorlack

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

les fichiers de ce répertoire crontabs/ doivent être exécutables par le propriétaire - octal 700

source: man cron et NNRooth

2
n611x007

La solution que j'utilise est la suivante:

  1. Modifiez crontab (utilisez la commande: crontab -e) pour exécuter le travail aussi souvent que nécessaire (toutes les minutes ou toutes les minutes).
  2. Modifiez le script Shell à exécuter à l’aide de cron pour imprimer la sortie dans un fichier (par exemple: echo "Fonctionne bien" >>
    output.txt)
  3. Vérifiez le fichier output.txt à l'aide de la commande: tail -f output.txt, qui imprimera les derniers ajouts dans ce fichier et vous permettra ainsi de suivre l'exécution du script.
2
Abhilash