Je dois pouvoir exécuter un script 20 fois par jour à des heures complètement aléatoires. Je veux également qu'il ne s'exécute qu'entre 9 h et 23 h.
Je suis familier avec la création de tâches cron sous linux.
Je dois pouvoir exécuter un script 20 fois par jour à des heures complètement aléatoires. Je veux également qu'il ne s'exécute qu'entre 9 h et 23 h.
Je suis familier avec la création de tâches cron sous linux.
Oui, oui, la question date de plus d'un an, mais je peux peut-être ajouter quelque chose d'utile :
Comment programmer quelque chose à un décalage aléatoire 20 fois par jour entre 9 h et 23 h ? C'est un peu délicat avec cron, car il faut diviser 14 heures par 20 exécutions. Je n'aime pas beaucoup les autres réponses car elles nécessitent d'écrire un wrapper bash script pour votre script php.
Toutefois, si vous me permettez d'assouplir la restriction de temps et de fréquence à 13 fois entre 8 h 30 et 23 h 09, cela pourrait faire l'affaire, tout en restant dans les limites de votre crontab :
30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php
${RANDOM:3:2} utilise le $RANDOM de bash que d'autres personnes ont mentionné ci-dessus, mais ajoute le découpage de tableau de bash. Comme les variables bash ne sont pas typées, le nombre pseudo-aléatoire signé de 16 bits est tronqué aux 2 premiers de ses 5 chiffres décimaux, ce qui vous donne une phrase succincte pour retarder votre cronjob de 10 à 99 minutes (bien que la distribution penche vers 10 à 32).
La méthode suivante pourrait également vous convenir, mais je l'ai trouvée "moins aléatoire" pour une raison quelconque (peut-être que la loi de Benford est déclenchée par la modulation de nombres pseudo-aléatoires). Hé, je ne sais pas, j'ai été recalé en maths... C'est la faute de Bash !) :
30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php
Vous devez rendre le module comme '\%' ci-dessus parce que cron (du moins, le 'vixie-cron' de Linux) termine la ligne lorsqu'il rencontre un '%' non encodé.
Vous pourriez peut-être obtenir les 7 autres script exécutions en ajoutant une autre ligne avec une autre plage de 7 heures. Ou relâchez votre restriction d'exécution entre 3h du matin et 11h du soir.
J'aime la réponse tardive. Mais si vous essayez de générer un entier aléatoire distribué uniformément dans la plage de 10 à 99, et que la sortie de RANDOM est de 0 à 32 767, pourquoi ne pas simplement faire $[(RANDOM/368)+10]
?
@jsdalton : L'opérateur modulo ne serait-il pas mieux ? $((RANDOM % 90 + 10))
Test : for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
Sur de nombreux systèmes, cron n'utilise pas bash par défaut, il est donc préférable d'éviter le bashisme. $RANDOM
: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m
.
Si je comprends ce que vous recherchez, vous devrez faire quelque chose d'un peu désordonné, comme avoir une tâche cron qui exécute un bash script qui randomise les temps d'exécution.... Quelque chose comme ça :
crontab :
0 9 * * * /path/to/bashscript
et dans /path/to/bashscript :
#!/bin/bash
maxdelay=$((14*60)) # 14 hours from 9am to 11pm, converted to minutes
for ((i=1; i<=20; i++)); do
delay=$(($RANDOM%maxdelay)) # pick an independent random delay for each of the 20 runs
(sleep $((delay*60)); /path/to/phpscript.php) & # background a subshell to wait, then run the php script
done
Quelques remarques : cette approche est un peu gaspilleuse de ressources, car elle déclenche 20 processus d'arrière-plan à 9 heures du matin, chacun d'entre eux attendant pendant un nombre aléatoire de minutes (jusqu'à 14 heures, c'est-à-dire 23 heures), puis lance le script php script et sort. De plus, comme elle utilise un nombre aléatoire de minutes (et non de secondes), les heures de début ne sont pas aussi aléatoires qu'elles pourraient l'être. Mais $RANDOM ne va que jusqu'à 32 767, et il y a 50 400 secondes entre 9h et 23h, ce serait un peu plus compliqué de randomiser les secondes également. Enfin, puisque les heures de démarrage sont aléatoires et indépendantes les unes des autres, il est possible (mais peu probable) que deux ou plusieurs instances du script soient lancées simultanément.
Vous pouvez rendre les affectations arithmétiques plus lisibles en supprimant le signe dollar et en déplaçant les doubles parenthèses vers la gauche (par ex. ((maxdelay = 14 * 60))
o ((delay = $RANDOM % maxdelay))
). Le site sleep
L'argument doit toujours être tel que vous l'avez (mais vous pouvez ajouter des espaces, si vous le souhaitez).
Cela a aussi fonctionné pour moi. Mon bash script personnalisé ressemble à ce qui suit sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Cron offre un RANDOM_DELAY
variable. Voir crontab(5)
pour les détails.
La variable RANDOM_DELAY permet de retarder le démarrage des tâches d'un nombre aléatoire de minutes. minutes, la limite supérieure étant spécifiée par la variable.
Cela se produit souvent dans anacron
mais peut également être utile dans un crontab
.
Vous devrez peut-être faire attention à cela si vous avez des tâches qui s'exécutent à une granularité fine (minute). (minute) et d'autres qui sont grossières.
J'aimerais utiliser la variable RANDOM_DELAY, mais je ne trouve aucune indication dans la page de manuel de crontab(5) sur Ubuntu 14.04.4 LTS.
C'est malheureux. Je me demande s'il n'est pas pris en charge là-bas. Je le vois documenté dans cette page de manuel sur Centos 7 et Arch Linux.
J'ai fini par utiliser sleep $(( 1$(date +%N) % 60 )) ; dostuffs
(compatible avec bash et sh)
Le préfixe 1 permet de forcer l'interprétation NON en base 8 de la date +%N (par exemple 00551454).
N'oubliez pas d'échapper à % en utilisant \% dans un fichier crontab
* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs
Si quelqu'un se demande, comme moi : %N fournit les nanos actuels, mais certaines pages de manuel manquent d'informations à ce sujet. Il s'agit d'une solution très intelligente pour les personnes qui ont juste besoin d'un "peu d'aléatoire" facilement par commande.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
La question n'est pas très bien posée. En fin de compte, vous voulez distribuer 20 points sur l'axe du temps entre 9 heures et 11 heures. Mais existe-t-il des contraintes sur la différence de temps minimale ? Ne rien faire entre 9h et 10h30 est-il acceptable ? La seule façon d'y parvenir de manière acceptable semble être l'idée de Klaus : sélectionnez vos 20 heures à 09:00, ce qui vous permet de respecter toutes les contraintes que vous pourriez avoir, puis programmez les choses avec "à".