J'ai un script configuré pour s'exécuter toutes les minutes. Mais dans le script que nous avons mentionné, si une condition est vraie, le script doit dormir pendant 5 minutes. Comment cela peut-il affecter la crontab ? Le script sera-t-il en mode veille pendant 5 minutes, ou s'exécutera-t-il à nouveau comme il a été défini dans la crontab toutes les 1min ?
Réponses
Trop de publicités?Vous avez deux possibilités pour y parvenir. Normalement, cron ne se préoccupe pas de savoir si l'instance précédente du job est toujours en cours d'exécution.
Option 1 :
Écrire un fichier de verrouillage au début du script et le supprimer lorsqu'il est terminé. Ensuite, une vérification au début du script vérifie si le fichier existe, et si oui, le script se termine sans rien faire. Cela pourrait par exemple ressembler à ceci :
# if the file exists (`-e`) end the script:
[ -e "/var/lock/myscript.pid" ] && exit
# if not create the file:
touch /var/lock/myscript.pid
...
# do whatever the script does.
# if condition
sleep 300 # wait 5 min
...
# remove the file when the script finishes:
rm /var/lock/myscript.pid
Option 2 :
Il existe également une utilité pour cela. Elle s'appelle run-one
. Extrait de la page de manuel :
run-one - exécute une seule instance à la fois d'une certaine commande unique d'arguments (utile pour les cronjobs, par exemple)
Le cronjob pourrait alors ressembler à ceci :
* * * * * /usr/bin/run-one /path/to/myscript
Avec crontab, vous ne pouvez pas le faire, mais vous pouvez le faire avec une petite extension de votre script. Je pense au pseudo-code suivant :
#!/bin/bash
if ...temporary_file_exists
then
if ...tmp_is_older_as_5_minute...
then
delete tmp
else
exit
fi
fi
...
if "${condition}"
then
touch $temporary_file
exit
fi
...normal behavior of your script...
Qu'est-ce qu'il fait ? Le principal problème des scripts cron scripts, c'est qu'il n'est pas possible d'avoir facilement une mémoire persistante entre leurs exécutions. Vous devez toujours utiliser des méthodes ad hoc. Dans le monde des scripts Unix, les fichiers temporaires sont des solutions très courantes pour cela, et vous utilisez l'existence (et le temps de changement) d'un fichier temporaire pour savoir quelle est la situation actuelle.
J'ai fait la même chose - mettre en pause un script si quelque chose se produisait, mais je ne l'ai pas exécuté à partir de cron. Au lieu de cela, j'avais un script script qui se ré-exécutait continuellement. Dans mon cas, je vérifiais la moyenne de la charge, et je faisais une pause d'une minute si elle était "trop élevée". Si elle était correcte, je faisais ce que je devais faire, puis je faisais une pause beaucoup plus courte.
Cela présente également le double avantage qu'il n'y aura jamais qu'un seul script en cours d'exécution, et que vous pouvez également le réexécuter plus souvent que toutes les minutes, ce qui est la fréquence minimale de cron.
#!/bin/bash
i_should_sleep() {
if [ *condition* ]
then
return 0
else
return 1
fi
}
if i_should_sleep; then
sleep 300
exec $0 $@
fi
nice COMMAND # run the action we really want to do
sleep 60 # or less than a minute, to run more often
exec $0 $@
Pour le démarrer, vous devez créer une tâche Upstart ou init.d, ou quelque chose de similaire.