174 votes

Exécution manuelle et immédiate d'une tâche cron

(J'ai déjà lu Comment puis-je tester un nouveau cron script ? .)

J'ai un problème spécifique (la tâche cron ne semble pas s'exécuter, ou s'exécuter correctement), mais le problème est général : J'aimerais déboguer les scripts qui sont cronnisés. Je suis conscient que je peux configurer une ligne * * * * * crontab, mais ce n'est pas une solution pleinement satisfaisante. J'aimerais pouvoir exécuter une tâche cron à partir de la ligne de commande comme si cron l'exécutait (même utilisateur, mêmes variables d'environnement, etc.). Existe-t-il un moyen de le faire ? Devoir attendre 60 secondes pour tester les changements de scripts n'est pas pratique.

0 votes

(désolé, je ne peux pas ajouter de commentaire) 0 30 16 20 * ? * même si vous exécutez le job comme ça, l'idée est de fournir une sortie script pour voir ce qui ne va pas à moins que le job n'écrive dans un log, c'est quuiet inutile.

1voto

Basj Points 479

Inspiré par la réponse de @DjangoJanny, voici ce que j'utilise pour lancer le travail à la 5ème ligne de mon crontab :

 eval "$(crontab -l | sed -n '5p' | tr -s ' ' | cut -d' ' -f 6-)"

Explication :

  • lance la commande donnée par :
  • affiche la crontab
  • obtient la 5e ligne
  • remplace les espaces multiples par un seul espace
  • prend tout de la 6ème colonne à la fin

0voto

Daniel Serodio Points 1841

Je n'ai jamais trouvé un moyen de lancer des tâches cron manuellement mais este suggère de configurer le même environnement que le cronjob et d'exécuter le script manuellement.

0 votes

Ce que vous proposez de faire n'est-il pas ce que le PO veut savoir faire ?

0 votes

C'est pourquoi j'ai inclus le lien vers l'article qui décrit comment le faire. Je n'ai pas jugé nécessaire de tout copier-coller ici.

0voto

AdrP Points 17

Vous pouvez programmer le travail pour qu'il commence la minute suivante :)

13 votes

59 secondes, c'est beaucoup de temps.

1 votes

Le PO a mentionné cette possibilité dans sa question : "Y a-t-il un moyen de faire cela ? Devoir attendre 60 secondes pour tester les changements de script n'est pas pratique."

0 votes

59 secondes, c'est probablement moins que ce qu'il faudrait pour choisir et mettre en œuvre l'une des autres solutions proposées (et dont le fonctionnement n'est pas garanti). Quand je vois de telles lacunes, je me demande comment Linux est devenu un système d'exploitation standard de facto pour les serveurs. Tout administrateur système sérieux ne voudrait-il pas tester son travail ?

0voto

Daladim Points 1

Exécuter une tâche comme le ferait cron est délicat. Elle nécessite un environnement modifié, un Shell non interactif, pas de terminal d'entrée attaché, et éventuellement aussi un Shell spécifique (par ex. bin/sh au lieu de /bin/bash ).

J'ai fait un script qui gère tous ces problèmes. Exécutez-le avec votre commande/script à exécuter comme premier argument, et vous êtes prêt à partir. Il est également hébergé (et éventuellement mis à jour dans Github ).

#!/bin/bash
# Run as if it was called from cron, that is to say:
#  * with a modified environment
#  * with a specific shell, which may or may not be bash
#  * without an attached input terminal
#  * in a non-interactive shell

function usage(){
    echo "$0 - Run a script or a command as it would be in a cron job, then display its output"
    echo "Usage:"
    echo "   $0 [command | script]"
}

if [ "$1" == "-h" -o "$1" == "--help" ]; then
    usage
    exit 0
fi

if [ $(whoami) != "root" ]; then
    echo "Only root is supported at the moment"
    exit 1
fi

# This file should contain the cron environment.
cron_env="/root/cron-env"
if [ ! -f "$cron_env" ]; then
    echo "Unable to find $cron_env"
    echo "To generate it, run \"/usr/bin/env > /root/cron-env\" as a cron job"
    exit 0
fi

# It will be a nightmare to expand "$@" inside a shell -c argument.
# Let's rather generate a string where we manually expand-and-quote the arguments
env_string="/usr/bin/env -i "
for envi in $(cat "$cron_env"); do
   env_string="${env_string} $envi "
done

cmd_string=""
for arg in "$@"; do
    cmd_string="${cmd_string} \"${arg}\" "
done

# Which shell should we use?
the_shell=$(grep -E "^SHELL=" /root/cron-env | sed 's/SHELL=//')
echo "Running with $the_shell the following command: $cmd_string"

# Let's route the output in a file
# and do not provide any input (so that the command is executed without an attached terminal)
so=$(mktemp "/tmp/fakecron.out.XXXX")
se=$(mktemp "/tmp/fakecron.err.XXXX")
"$the_shell" -c "$env_string $cmd_string" >"$so" 2>"$se" < /dev/null

echo -e "Done. Here is \033[1mstdout\033[0m:"
cat "$so"
echo -e "Done. Here is \033[1mstderr\033[0m:"
cat "$se"
rm "$so" "$se"

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X