Je veux exécuter un script shell littéralement tous les 3 jours. L'utilisation de crontab avec 01 00 */3 * *
ne remplira pas réellement la condition, car elle s'exécuterait le 31 puis le 1er jour d'un mois. La */3
syntaxe est la même que pour dire 1,4,7 ... 25,28,31.
Il devrait y avoir des moyens pour que le script lui-même vérifie les conditions et quitte si 3 jours ne se sont pas écoulés. Donc crontab exécute le script tous les jours, mais le script lui-même vérifierait si 3 jours se sont écoulés.
J'ai même trouvé du code, mais cela m'a donné une erreur de syntaxe, toute aide serait appréciée.
if (! (date("z") % 3)) {
exit;
}
main.sh: line 1: syntax error near unexpected token `"z"'
main.sh: line 1: `if (! (date("z") % 3)) {'
command-line
bash
scripts
cron
Taavi
la source
la source
*/3
ne marche pas? "si 3 jours ne se sont pas écoulés": trois jours depuis quoi? Veuillez modifier votre question et clarifier.date("z") % 3 == 0
souffrirait d'un problème similaire: la condition sera fausse pendant les quatre jours entre le 29 décembre et le 3 janvier, à moins que ce décembre ne fasse partie d'une année bissextile.Réponses:
Pour abandonner et quitter immédiatement un script si la dernière exécution ne remonte pas à au moins une heure spécifique, vous pouvez utiliser cette méthode qui nécessite un fichier externe qui stocke la dernière date et heure d'exécution.
Ajoutez ces lignes en haut de votre script Bash:
N'oubliez pas de définir une valeur significative
datefile=
et d'adapter la valeur deseconds=
à vos besoins ($((60*60*24*3))
évaluation à 3 jours).Si vous ne voulez pas de fichier séparé, vous pouvez également stocker la dernière heure d'exécution dans l'horodatage de modification de votre script. Cela signifie cependant que toute modification de votre fichier de script réinitialisera le compteur 3 et sera traitée comme si le script était en cours d'exécution.
Pour implémenter cela, ajoutez l'extrait ci-dessous en haut de votre fichier de script:
Encore une fois, n'oubliez pas d'adapter la valeur de
seconds=
à vos besoins ($((60*60*24*3))
évalue à 3 jours).la source
$[ $(date +%s) - $(< lastrun) ]
. Si le script est exécuté depuis cron une fois par jour, je pourrais ajouter un peu de mou à l'intervalle de temps requis, de sorte que si l'exécution du script est retardée de quelques secondes, la prochaine fois ne sautera pas une journée entière. C'est vérifier chaque jour si 71 heures se sont écoulées.Cron n'est vraiment pas le bon outil pour cela. Il y a en fait un outil couramment utilisé et underloved appelé à laquelle le travail de force. at est principalement conçu pour une utilisation interactive et je suis sûr que quelqu'un trouverait une meilleure façon de le faire.
Dans mon cas, j'aurais le script que j'exécute répertorié dans testjobs.txt, et inclure une ligne qui lit.
Par exemple, j'aurais ceci comme testjobs.txt
J'ai deux ordres innocents, qui pourraient être vos scripts d'obus. J'exécute echo pour m'assurer d'avoir une sortie déterministe et une date pour confirmer que la commande s'exécute selon les besoins. Lorsque at exécute cette commande, elle se termine en ajoutant un nouveau travail à at pendant 3 jours. (J'ai testé avec une minute - ce qui fonctionne)
Je suis sûr que je serai appelé pour la manière dont j'ai abusé, mais c'est un outil pratique pour planifier une commande à exécuter à un moment ou x jours après une commande précédente.
la source
at
semble la meilleure approche ici.Le problème avec cette approche est que chaque fois que vous exécutez manuellement le script, vous ajoutez un autre ensemble deat
tâches tous les 3 jours .at
est en haut, ou potentiellement beaucoup plus siat
est près du bas d'un script à longue exécution)Tout d'abord, le fragment de code ci-dessus n'est pas une syntaxe Bash non valide, ressemble à Perl. Deuxièmement, le
z
paramètre ledate
fait sortir le fuseau horaire numérique.+%j
est le numéro du jour. Vous avez besoin:Mais vous allez toujours voir l'étrangeté à la fin de l'année:
Vous pourriez avoir plus de chance de conserver un décompte dans un fichier et de le tester / le mettre à jour.
la source
date()
fonction intégrée, mais cela ressemble un peu à date () en PHP (oùz
est "Le jour de l'année (à partir de 0)")Si vous pouvez simplement laisser le script s'exécuter perpétuellement, vous pouvez le faire:
Cette boucle est toujours vraie, elle exécutera donc toujours le code, puis attendra trois jours avant de recommencer la boucle.
la source
while true
?at
solution, cela dérivera par le temps d'exécution du script à chaque exécution. Bien sûr, cela peut être contourné en économisant le moment où le script démarre et en dormant jusqu'à 3 jours à partir de cela.Vous pouvez utiliser anacron au lieu de cron, il est conçu exactement pour faire ce dont vous avez besoin. Depuis la page de manuel:
la source