Cron en cours d'exécution toutes les 15 secondes


18

Pourriez-vous me conseiller quoi écrire crontabpour qu'il exécute un travail (pour les tests que j'utiliserai /usr/bin/chromium-browser) toutes les 15 secondes?


Au lieu de crontab, comptez sur un autre système de gestion d'événements, par exemple: le module every.pm de Perl vous y aidera.
Nikhil Mulley

Réponses:


27

Vous ne pouvez pas descendre en dessous d'une granularité d'une minute avec cron. Ce que vous pouvez faire, c'est, chaque minute, exécuter un script qui exécute votre travail, attend 15 secondes et se répète. La ligne crontab suivante démarre some_jobtoutes les 15 secondes.

* * * * * for i in 0 1 2; do some_job & sleep 15; done; some_job

Ce script suppose que le travail ne prendra jamais plus de 15 secondes. Le script légèrement plus complexe suivant prend soin de ne pas exécuter l'instance suivante si celle-ci prenait trop de temps à s'exécuter. Il repose sur la prise en datecharge du %sformat (par exemple GNU ou Busybox, donc tout ira bien sous Linux). Si vous le mettez directement dans une crontab, notez que les %caractères doivent être écrits comme \%dans une ligne crontab.

end=$(($(date +%s) + 45))
while true; do
  some_job &
  [ $(date +%s) -ge $end ] && break
  sleep 15
  wait
done
[ $(date +%s) -ge $(($end + 15)) ] || some_job

Je noterai cependant que si vous devez exécuter un travail aussi souvent que toutes les 15 secondes, cron est probablement la mauvaise approche. Bien que les unités soient bonnes avec des processus de courte durée, les frais généraux liés au lancement d'un programme toutes les 15 secondes peuvent être non négligeables (selon la demande du programme). Vous ne pouvez pas exécuter votre application tout le temps et lui faire exécuter sa tâche toutes les 15 secondes?


pourrait également être: pour i in 1 2 3 4 ; do some_job & sleep 15; done(le dernier sommeil n'affectera pas la prochaine exécution), mais la façon dont vous le faites est probablement meilleure pour le timing du courrier cronjob sortant (envoyé juste après le dernier some_job, au lieu de 15s plus tard dans ma variante)
Olivier Dulac


13

Approche différente des autres: exécutez 4 cronjobs, chacun décalé de 15 secondes:

* * * * * sleep 00; timeout 15s some_job
* * * * * sleep 15; timeout 15s some_job
* * * * * sleep 30; timeout 15s some_job
* * * * * sleep 45; timeout 15s some_job

Pour éviter que le travail n'interfère avec lui-même, nous limitons son temps d'exécution à 15 secondes via GNU coreutils ' timeoutpour chaque travail. Notez cependant que si le travail ne se termine pas correctement immédiatement au bout de 15 secondes, vous pouvez toujours vous retrouver avec des problèmes. Consultez le manuel de commande pour plus de détails sur la façon de résoudre ce problème en cas de problème. Notez également que si la commande prend plus de 15 secondes et que le délai d'attente la tue, vous obtiendrez un état de sortie non nul qui déclenchera un e-mail cronjob.


Brillant, quoique répétitif.
Mike Kormendy

1
Agréable. Si un processus est long, le processus suivant se terminera probablement également sur un noyau différent. Je ne sais pas si vous pouvez définir délibérément l'affinité de base pour les tâches Cron, mais cela pourrait rendre cette approche encore meilleure.
Tim

@Tim bon point. Je l'ai abordé un peu dans un montage.
Otheus

2

En bref, le cron n'est pas si granuleux avec le temps. La période la plus courte que vous obtiendrez est de 1 min.

#       .---------------- minute (0 - 59)
#       |       .------------- hour (0 - 23)
#       |       |       .---------- day of month (1 - 31)
#       |       |       |       .------- month (1 - 12) OR jan,feb,mar,apr ...
#       |       |       |       |       .----- day of week (0 - 6) (Sunday=0 or 7)  OR sun,mon,tue,wed,thu,fri,sat
#       |       |       |       |       |
#       *       *       *       *       *       command to be executed
        *       *       *       *       /usr/bin/chromium-browser

Cependant, vous pourriez écrire un script qui s'exécuterait toutes les 15 secondes ...


J'ai une ligne * * * * * /usr/bin/chromium-browserdans crontab. Selon le manuel, il devrait fonctionner toutes les minutes mais rien ne fonctionne.
xralf

Est-il difficile d'écrire un tel script? Dois-je poser une autre question ou pourrait-elle être écrite ici?
xralf

Les tâches Cron n'ont pas de terminal, je m'attends donc à ce que le navigateur échoue. Il peut le faire en silence.
BillThor

Mes journaux cron sont situés dans / var / log / cron pour les dérivés de redhat, ie. fedora, centos, etc. Cela peut aussi vous aider à décrire exactement ce que vous essayez de faire pour que les gens aient une image complète de ce qui se passe.
rfelsburg

1

Dans votre crontab:

* * * *  /usr/bin/chromium-browser_starter

Puis dans /usr/bin/chromium-browser_starter:

#!/bin/sh

# chromium-browser_starter
#
# Schedules /usr/bin/chromium-browser to run every 15 seconds for a minute.
# Intended to be called every minute through crond(8).

for ((secs=0; secs<46; secs+=15)); do
    (sleep $secs; /usr/bin/chromium-browser "$@") &
done

wait

Lorsque j'écris ps aux | grep chromaprès une minute, je ne vois pas le navigateur Chrome fonctionner.
xralf

@xralf - Le script ne s'exécute que pendant quelques secondes au maximum. Essayez de chercher sleep.
amphetamachine
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.