J'ai besoin de la capacité d'exécuter un script PHP 20 fois par jour à des moments complètement aléatoires. Je veux également qu'il ne fonctionne qu'entre 9h et 23h.
Je suis familier avec la création de tâches cron sous Linux.
J'ai besoin de la capacité d'exécuter un script PHP 20 fois par jour à des moments complètement aléatoires. Je veux également qu'il ne fonctionne qu'entre 9h et 23h.
Je suis familier avec la création de tâches cron sous Linux.
Réponses:
Si je comprends ce que vous cherchez, vous devrez faire quelque chose d'un peu compliqué, comme avoir un travail cron qui exécute un script bash qui randomise les temps d'exécution ... Quelque chose comme ceci:
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 notes: cette approche est un peu un gaspillage de ressources, car elle déclenche 20 processus d'arrière-plan à 9h, chacun attend pendant un nombre aléatoire de minutes (jusqu'à 14 heures, soit 23h), puis lance le script php et sorties. De plus, comme il 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 monte 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ébut 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.
((maxdelay = 14 * 60))
ou ((delay = $RANDOM % maxdelay))
). L' sleep
argument doit toujours être tel que vous l'avez (bien que vous puissiez ajouter des espaces, si vous le souhaitez).
sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Ouais, ouais, la question a plus d'un an, mais je peux peut-être ajouter quelque chose d'utile:
Comment cron quelque chose avec un décalage aléatoire 20 fois par jour entre 9h et 23h? C'est un peu délicat dans cron, car vous divisez 14 heures par 20 temps d'exécution. Je n'aime pas beaucoup les autres réponses car elles nécessitent l'écriture d'un script wrapper bash pour votre script php.
Cependant, si vous me permettez la liberté d'assouplir la restriction de synchronisation et de fréquence à 13 fois entre 8h30 et 23h09, cela pourrait faire l'affaire, et le tout 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 du tableau bash. Étant donné que les variables bash ne sont pas typées, le nombre 16 bits signé pseudo-aléatoire est tronqué aux 2 premiers de ses 5 chiffres décimaux, vous donnant une ligne succincte pour retarder votre travail cron entre 10 et 99 minutes (bien que la distribution soit biaisée vers 10 à 32).
Ce qui suit pourrait également fonctionner pour vous, mais j'ai trouvé que c'était "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 raté les mathématiques ... sur bash!):
30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php
Vous devez rendre le module comme '\%' ci-dessus car cron (enfin, au moins Linux 'vixie-cron') termine la ligne quand il rencontre un '%' sans échappement.
Peut-être que vous pourriez obtenir les 7 autres exécutions de script en ajoutant une autre ligne avec une autre plage de 7 heures. Ou relâchez votre restriction pour courir entre 3 h et 23 h.
$[(RANDOM/368)+10]
?
$((RANDOM % 90 + 10))
Test:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
$RANDOM
: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m
.
crontab
utilise bash
avant de l'utiliser $RANDOM
. Si vous avez vixie-cron
(semble être mon cas sur Ubuntu), vous pouvez ajouter SHELL=/bin/bash
en haut. Il y a plus d'alternatives pour d'autres versions de cron ici: superuser.com/a/264541/260350
crontab: errors in crontab file, can't install. Do you want to retry the same edit?
aide s'il vous plaît
J'utilise donc ce qui suit pour exécuter une commande entre 1h00 et 330h00
0 1 * * * perl -le 'sleep rand 9000' && *command goes here*
Cela a pris soin de mes besoins aléatoires pour moi. Cela représente 9000 secondes == 150 minutes == 2,5 heures
Cron propose une RANDOM_DELAY
variable. Voir crontab(5)
pour plus de détails.
La variable RANDOM_DELAY permet de retarder le démarrage des travaux par une quantité aléatoire de minutes avec une limite supérieure spécifiée par la variable.
Cela se voit couramment dans les anacron
emplois, mais peut également être utile dans un fichier crontab
.
Vous devrez peut-être faire attention à cela si vous avez des travaux qui s'exécutent avec une granularité fine (minute) et d'autres qui sont grossiers.
RANDOM_DELAY
est établi une fois et reste constant pendant tout le temps d'exécution du démon.
RANDOM_DELAY
drapeau est une caractéristique de cronie-crond alors qu'Ubuntu semble fonctionner, vixie-cron
ce qui n'a pas cet indicateur.
Ma première pensée serait de créer une tâche cron en lançant 20 tâches planifiées au hasard. L' at
utilitaire (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) est utilisé pour exécuter des commandes à un moment spécifié.
J'ai fini par utiliser sleep $(( 1$(date +%N) % 60 )) ; dostuffs
(compatible avec bash & sh)
Le préfixe 1 est de forcer l'interprétation NON 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
date
(ce que vous faites probablement sur la plupart des Linux, mais pas sur Busybox, MacOS standard ou diverses autres plates-formes dérivées de BSD).
La solution d'al-x ne fonctionne pas pour moi puisque les commandes crontab ne sont pas exécutées dans bash mais dans sh je suppose. Ce qui fonctionne, c'est:
30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
$[ ... ]
est une syntaxe déconseillée depuis waaaay back; pour tout ce qui date de ce millénaire, vous préféreriez $((RANDOM\%90))m
quelle syntaxe est compatible POSIX (mais bien sûr, RANDOM
c'est toujours uniquement Bash).
at -f [file] [timespec]
ou
echo [command] | at [timespec]
ou
at [timespec]
... et des spécifications interactives comme script
l'enregistrement de.
At exécute le texte fourni sur stdin ou dans le fichier spécifié par -f [file]
.
Voici la [timespec]
grammaire . Cela peut être quelque chose comme:
0100
, 2359
,1620
now + 10 minutes
2071-05-31 - 5 hours 12 minutes UTC
Si vous spécifiez explicitement le fuseau horaire, certaines versions de timespec peuvent n'autoriser UTC
que l'argument de fuseau horaire facultatif.
cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Vous pouvez tester l'analyse bash en pré-en attente echo
et en échappant le |
(pipe).
echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Pour voir les travaux planifiés, l'utilisation atq
et le contenu des travaux (variables d'environnement, configuration et commande / script) avec at -c [jobid]
.
Le système fait partie de cron et l'invite interactive capture en fait tout l'état actuel de votre shell, vous pouvez donc exécuter des commandes sans spécifier de chemins absolus.
Pour ceux qui ont parcouru le chemin ici:
Si vous utilisez anacron (bureau et ordinateur portable Ubuntu), vous pouvez modifier
/etc/anacrontab
et ajouter
RANDOM_DELAY=XX
Où XX est le nombre de minutes que vous souhaitez retarder le travail de base.
Anacron est comme cron mais il ne s'attend pas à ce que votre ordinateur soit en mode 24x7 (comme nos ordinateurs portables) et exécutera les scripts qu'il a manqués parce que le système était en panne.
Vous pouvez essayer avec cet exemple d'utiliser des temps aléatoires avant d'exécuter la commande:
#!/bin/bash
# start time
date +"%H:%M:%S"
# sleep for 5 seconds
sleep $(shuf -i 1-25 -n 1)
# end time
date +"%H:%M:%S"
Qu'en est-il de la création d'un script qui réécrit la crontab tous les jours?
Je me rends compte que c'est un fil plus ancien, mais je veux ajouter un élément lié à une valeur aléatoire que j'utilise beaucoup. Au lieu d'utiliser la variable $ RANDOM avec une plage fixe et limitée, je crée souvent des valeurs aléatoires de plage arbitraire dans le shell avec
dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none
afin que vous puissiez faire, par exemple,
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)
et surmonter certaines des restrictions qui ont été discutées dans ce fil.
~$info dd
et je peux comprendre ce qui se passe sur le côté gauche de |
, mais je ne peux pas distinguer le côté droit. Donc, pour moi et pour d'autres intéressés par overcoming some restrictions
la génération de valeur aléatoire, pourquoi ne pas prendre un moment pour expliquer le RHS et faire un argumentaire plus fort pour utiliser votre approche. La profondeur de l'explication rend les gens à l'aise avec le processus que vous suggérez et ses avantages. Merci.