Puis-je exécuter un travail cron plus souvent que chaque minute?

44

Est-il possible d'exécuter une tâche cron toutes les 30 secondes sans commande de veille?

utilisateur15336
la source
4
Quelle est votre intention? Cron est-il le bon outil à utiliser pour cela?
Manuel Faux
Bonne question.
Preet Sangha
Par exemple, j’utilise actuellement cron pour modifier l’image d’arrière-plan de mon bureau afin de contourner les limitations du sélecteur d’image d’arrière-plan natif (et non de plonger dans les sous-répertoires). Si je voulais changer plus d'une fois par minute, je rencontrais cette limitation cron. (bien que le sélecteur de bg natif ait la même limitation)
donquixote

Réponses:

36

Si votre tâche doit être exécutée aussi souvent, cron est le mauvais outil. Outre le fait qu'il ne lancera tout simplement pas des travaux aussi souvent, vous risquez également de graves problèmes si l'exécution du travail prend plus de temps que l'intervalle entre les lancements. Réécrivez votre tâche pour la démoniser et l'exécuter de manière persistante, puis lancez-la à partir de cron si nécessaire (tout en vous assurant qu'elle ne se relancera pas si elle est déjà en cours d'exécution).

crépuscule
la source
18
La partie "vous risquez également de graves problèmes si le travail prend plus de temps que l'intervalle entre les lancements." Ce n'est pas vrai et si c'était le cas, cela s'appliquerait de la même manière aux travaux qui passent toutes les 5 minutes, toutes les heures ou tous les mois. Ce problème a des solutions (utiliser un pidfile ou autre et vérifier si le travail est déjà en cours d'exécution avant de l'exécuter). Le problème est donc que cron ne permettra tout simplement pas cette fréquence, mais il est incorrect de dire qu’il ya quelque chose de fondamentalement faux dans l’exécution d’une tâche toutes les moins d’une minute.
Matteo
2
Je voulais dire si vous n'utilisez pas un pidfile. Si votre travail s'exécute toutes les X minutes et prend plus de X minutes, vous vous retrouverez avec une accumulation de travaux. Si votre travail est également limité par une sorte de ressource (processeur, bande passante réseau / disque, etc.), son exécution répétitive accélérera encore le processus, et votre ordinateur finira par se transformer en désordre passionnant.
Crépuscule
2
Vous pouvez vous run-oneassurer qu'un programme / même un script PHP ne démarre pas une instance en double. sudo apt-get install run-oneet appelez-le parrun-one <normal command>
Kouton
3
Comme le montrent les réponses plus loin, c’est très bien possible, bien qu’un peu rusé. Pourquoi vous le faites mal !!!! la réponse acceptée ici, quand il ne répond pas du tout à la question?
Quelqu'un
@Mantriur Parce que l'auteur de la question l'a trouvée utile et l'a marquée comme la réponse acceptée? :) Mais sérieusement, vous avez déjà identifié le problème vous-même: de nombreuses autres réponses contemporaines ont proposé des solutions inédites qu'il serait peu judicieux d'utiliser dans un système de production. (De plus, gardez à l'esprit que plusieurs des autres réponses ne sont
apparues
37

Candidat pour l' utilisation la plus créative d'une commande Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

Si yourprogconsiste en:

date +%M.%S.%N >> yourprog.out

alors yourprog.outpourrait ressembler à:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

indiquant un assez bon niveau de précision.

Voici une explication des parties de la commande:

  • nohup- Ceci empêche la commande qui la suit, watchdans ce cas, de sortir lorsque le terminal quitte.
  • watch- Ce programme exécute une commande à plusieurs reprises. Normalement, le premier écran de sortie de la commande est affiché à chaque watchexécution de la commande.
  • -n 30- L'intervalle auquel exécuter la commande. Dans ce cas, c'est toutes les trente secondes.
  • --precise- Sans cette option, watchexécute la commande après un intervalle de secondes. Avec elle, chaque début de commande commence sur l’intervalle, si possible. Si cette option n'était pas spécifiée dans l'exemple, les heures seraient plus longues et plus longues de plus de 30 secondes à chaque fois en raison du temps nécessaire au lancement et à l'exécution de la commande ( yourprog).
  • yourprog- Le programme ou la ligne de commande watchà exécuter. Si la ligne de commande contient des caractères spéciaux pour le shell (par exemple, un espace ou un point-virgule), vous devrez la citer.
  • >/dev/null- L'supérieur à redirige la sortie de la commande en cours d' exécution par watchun fichier, /dev/null. Ce fichier supprime toutes les données écrites. Cela évite que la sortie ne soit écrite à l'écran ou, étant donné qu'elle nohupest utilisée, elle empêche l'envoi de la sortie dans un fichier appelé nohup.out.
  • &- La watchcommande est exécutée en arrière-plan et le contrôle est renvoyé au terminal ou au processus parent.

Notez que nohupla redirection de la sortie et l' &opérateur de contrôle en arrière - plan ne sont pas spécifiques à watch.

Voici une explication de l'exemple de yourprogscript:

  • date- Affiche la date et / ou l'heure actuelles. Il peut aussi les définir.
  • +%M.%S.%N- Ceci spécifie le format de sortie dateà utiliser. %Mest la minute actuelle, %Sla seconde actuelle et %Nla nanoseconde actuelle.
  • >> yourprog.out- Ceci redirige la sortie de la datecommande vers un fichier appelé yourprog.out. Le double supérieur à que entraîne l'ajout de la sortie au fichier à chaque appel plutôt que le contenu précédent étant écrasé.

Modifier :

Une autre chose qui pourrait être maltraitée (ou peut-être une utilisation légitime) est la minuterie système.

Voir systemd / Timers comme un remplacement cron et les timers Cron vs systemd .

Je vais essayer de poster un exemple bientôt.

En pause jusqu'à nouvel ordre.
la source
6
Je donne +1 pour pure joue
Matt Simmons
2
Ce serait bien d'avoir un peu plus d'explications avec cette réponse. La commande nohup est nouvelle pour moi. Internet me dit que c'est ignorer le signal de raccrochage. Ce qui me laisse encore confus.
DONQUIXOTE
2
@donquixote: Il est important de reconnaître que la commande dans son ensemble dans ma réponse n'est pas une chose recommandée à faire, d'où l'utilisation du mot "abus". Cependant, afin de clarifier un peu les choses pour vous car il y a des techniques utiles incluses, je vais essayer de décrire quelques-unes. Cela &provoque l'exécution de la commande en arrière-plan, rendant immédiatement le contrôle à l'invite de commande. L'utilisation de la nohupcommande force le processus en arrière-plan (dans ce cas watch) à ignorer le signal de raccrochage envoyé lors de la fermeture du shell, par exemple lorsque vous fermez le terminal. ...
pause jusqu'à nouvel ordre.
1
... Le fait de rediriger la sortie à l'aide >/dev/nullentraîne l'élimination de la sortie et empêche la création d'un nohup.outfichier qui serait autrement créé lorsque la sortie standard est un terminal.
pause jusqu'à nouvel ordre.
1
@donquixote: Pas dans 30 secondes, toutes les 30 secondes. Le reste consiste à le laisser fonctionner sans surveillance en arrière-plan pour lui donner un aspect plus cron. Si vous voulez utiliser sleep, vous devez écrire une boucle pour que le processus se répète (le watchrépète pour vous, comme vous le feriez cron). Vous auriez encore besoin nohupet &. Un problème supplémentaire sleepserait la dérive temporelle. L' --preciseoption watchévite cela. Sans lui ou lors de l'utilisation sleepdans une boucle, l'intervalle de temps a le temps nécessaire pour que les commandes ou le script soient exécutés, afin que chaque exécution soit postérieure et ultérieure à ...
pause jusqu'à nouvel avis.
13

Cron est conçu pour se réveiller à chaque minute, il est donc impossible de le faire sans piratage, par exemple en dormant comme vous l'avez mentionné.

Balázs Pozsár
la source
10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

N'oubliez pas d'écrire quelque chose dans votre programme pour qu'il se termine si une instance précédente est déjà en cours d'exécution.

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

Bien sûr, cela ne laisse que très peu d’occasions d’échec. Recherchez donc sur Google une meilleure solution applicable à votre environnement.

Ghoti
la source
il a été demandé:without a sleep command
philippe
10
Les autres visiteurs trouvent cette question
indifférent
8

Vous pouvez le faire avec un logiciel tiers.

Une option qui a bien fonctionné pour moi est fréquente-cron

Il permet une précision en millisecondes et vous offre la possibilité de différer la prochaine exécution jusqu'à la fin de l'exécution en cours.

ça
la source
1
Frequent-cron a également bien fonctionné pour nous et alimente bon nombre de nos systèmes de production. Nous n'avons jamais eu de problème avec cela.
Homer6
2

J'aurais quelques préoccupations:

(1) Parfois, un système est occupé et ne peut pas démarrer les choses exactement au bout de 30 secondes. Il est alors possible qu’au même moment que vous exécutiez un travail, un autre travail apparaisse et que vous ayez alors 2 travaux (ou plus) faisant la même chose. chose. Selon le script, il peut y avoir une interférence significative ici. Ainsi, le codage dans un tel script devrait contenir du code afin de s’assurer qu’une seule instance du script donné est exécutée en même temps.

(2) Le script peut avoir beaucoup de temps système et consommer plus de ressources système que vous ne le souhaitez. Cela est vrai si vous êtes en compétition avec beaucoup d'autres activités du système.

Ainsi, comme l'a indiqué une personne, dans ce cas, j’envisagerais sérieusement de mettre en place un démon fonctionnant avec des processus supplémentaires afin de s’assurer qu’il continue de fonctionner s’il revêt une importance cruciale pour vos opérations.

mdpc
la source
1

Ma solution la plus simple et la plus préférée pour cette tâche:

entrée cron:
* * * * * flock -w0 /path/to/script /path/to/script

scénario:
while true;do echo doing something; sleep 10s;done

alternative paresseuse: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

ou

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

avantages

  • L'utilisation de la flockcommande évite d'exécuter le script par plusieurs instances en même temps. Cela peut être très important dans la plupart des cas.
  • flocket les watchcommandes sont disponibles sur la plupart des installations Linux

les inconvénients

  • L'arrêt de ce type de "service" nécessite deux étapes
    • commentez l'entrée cron
    • tuer le script ou la watchcommande
Asvany
la source
2
Quelqu'un peut-il expliquer cela à un débutant linux - avec des avantages et des inconvénients? Merci ..
a20
@asvany Je pense que j'aime cette solution, mais en tant que a20, pourriez-vous poster quelques explications sur le "vert" de Linux, s'il vous plaît? ty.
JoelAZ
0

Une solution, si c'est pour votre propre script ou si vous pouvez l'envelopper:

  1. Obtenez et rappelez-vous l'heure de début.
  2. Si un fichier de verrouillage, que vous allez toucher plus tard, est présent et que le script n'a pas été exécuté pendant 60 secondes, attendez une seconde et vérifiez à nouveau. (par exemple pendant / dormir) *
  3. Si le fichier de verrouillage est toujours présent au bout de 60 secondes, quittez avec un avertissement de verrouillage obsolète.
  4. Touchez verrouiller le fichier.
  5. Pendant que le script n'a pas été exécuté pendant 60 secondes, bouclez votre tâche réelle avec la durée de sommeil souhaitée.
  6. Supprimer le fichier de verrouillage.
  7. Ajouter comme cron minutieusement.
  8. Bob est ton oncle.

Moins de maux de tête que de construire et de surveiller un démon.

* Si vous utilisez PHP, rappelez-vous clearstatcache ().

Quelqu'un
la source