Trabajos de cron y tiempos aleatorios, dentro de horas determinadas

Necesito la capacidad de ejecutar un script PHP 20 veces al día en momentos completamente aleatorios. También quiero que se ejecute solo entre las 9am y las 11pm.

Estoy familiarizado con la creación de trabajos cron en Linux.

Si entiendo lo que estás buscando, necesitarás hacer algo un poco desordenado, como tener un trabajo cron que ejecute un script bash que aleatorice los tiempos de ejecución … Algo como esto:

crontab:

0 9 * * * /path/to/bashscript 

y en / 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 

Algunas notas: este enfoque es un desperdicio de recursos, ya que dispara 20 procesos en segundo plano a las 9 a.m., cada uno de los cuales espera un número aleatorio de minutos (hasta 14 horas, es decir, 11 p.m.), luego inicia el script php y salidas. Además, dado que usa una cantidad aleatoria de minutos (no segundos), los tiempos de inicio no son tan aleatorios como podrían ser. Pero $ RANDOM solo sube a 32,767, y hay 50,400 segundos entre las 9am y las 11pm, sería un poco más complicado aleatorizar los segundos también. Finalmente, dado que las horas de inicio son aleatorias e independientes entre sí, es posible (pero no muy probable) que dos o más instancias del script se inicien simultáneamente.

Sí, sí, la pregunta tiene más de un año, pero tal vez pueda agregar algo útil:

¿Cómo progtwigr algo en un desplazamiento aleatorio 20 veces al día entre las 9am y las 11pm? Eso es un poco complicado dentro de cron, porque estás dividiendo 14 horas por 20 veces de ejecución. No me gustan mucho las otras respuestas porque requieren escribir un script bash wrapper para tu script php.

Sin embargo, si me permites la libertad de reducir la restricción de tiempo y frecuencia a 13 veces entre las 8:30 a.m. y las 11:09 p.m., esto podría funcionar, y todo dentro de los límites de tu crontab:

 30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php 

$ {RANDOM: 3: 2} usa bash’s $ RANDOM que otras personas han mencionado anteriormente, pero agrega bash array slicing. Dado que las variables bash están sin tipo, el número pseudoaleatorio de 16 bits se trunca a los primeros 2 de sus 5 dígitos decimales, lo que le proporciona un trazo sucinto para retrasar su cronjob entre 10 y 99 minutos (aunque la distribución es sesgada hacia 10 a 32).

Lo siguiente también podría funcionar para ti, pero descubrí que es “menos aleatorio” por alguna razón (quizás la Ley de Benford se desencadene modulando números pseudoaleatorios. Oye, no sé, fallé las matemáticas … La culpa es en bash!):

 30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php 

Necesita representar el módulo como ‘\%’ arriba porque cron (bueno, al menos Linux ‘vixie-cron’) termina la línea cuando encuentra un ‘%’ no guardado.

Tal vez podría obtener las 7 ejecuciones de script restantes agregando otra línea con otro rango de 7 horas. O relaje su restricción para correr entre las 3am y las 11pm.

Así que estoy usando lo siguiente para ejecutar un comando entre 1AM y 330AM

 0 1 * * * perl -le 'sleep rand 9000' && *command goes here* 

Eso ha estado ocupándome de mis necesidades al azar. Eso es 9000 segundos == 150 minutos == 2.5 horas

Cron ofrece una variable RANDOM_DELAY . Ver crontab(5) para detalles.

La variable RANDOM_DELAY permite retrasar el inicio de trabajos por cantidad aleatoria de minutos con el límite superior especificado por la variable.

Esto se ve comúnmente en trabajos anacron , pero también puede ser útil en un crontab .

Es posible que deba tener cuidado con esto si tiene trabajos que se ejecutan en granularidad fina (minutos) y otros que son gruesos.

Lo primero que pensé fue crear un trabajo cron que lanzara 20 progtwigdos aleatoriamente en los trabajos. La utilidad at (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) se usa para ejecutar comandos a la hora especificada.

Terminé usando sleep $(( 1$(date +%N) % 60 )) ; dostuffs sleep $(( 1$(date +%N) % 60 )) ; dostuffs (bash & sh compatible)

El prefijo 1 es forzar la interpretación NON base 8 de la fecha +% N (por ejemplo, 00551454)

No te olvides de escapar% usando \% en un archivo crontab

* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs

at -f [file] [timespec]

o

echo [command] | at [timespec]

o

at [timespec] … y especificación interactiva como la grabación de script .

Mando

En ejecuciones, el texto se proporciona en stdin o en el archivo especificado por -f [file] .

Timespec

Aquí está la gramática [timespec] . Puede ser algo como:

  • Hora de 24 horas como int. De 4 dígitos, p. Ej. 0100 , 2359 , 1620
  • now + 10 minutes
  • 2071-05-31 - 5 hours 12 minutes UTC

Si especifica explícitamente la zona horaria, algunas versiones de la especificación de tiempo solo podrían permitir el UTC para el argumento opcional de la zona horaria.

Ejemplo

cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Pruébalo…

Puede probar el análisis de bash mediante echo previo a la echo y escapando | (tubo).

echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Para ver trabajos progtwigdos, use atq y los contenidos del trabajo ( atq entorno, configuración y comando / script) con at -c [jobid] .

Nota

El sistema es parte de cron, y el mensaje interactivo en realidad captura todo el estado actual de su caparazón, por lo que puede ejecutar comandos sin especificar rutas absolutas.

Para aquellos que buscaron en Google el camino hasta aquí:

Si está usando anacron (computadora de escritorio y portátil Ubuntu), puede editar

 /etc/anacrontab 

y añadir

 RANDOM_DELAY=XX 

Donde XX es la cantidad de minutos que desea retrasar el trabajo base.

Anacron es como cron, pero no espera que su computadora esté disponible las 24 horas, los 7 días de la semana (como nuestras computadoras portátiles) y ejecutará las secuencias de comandos que se perdió porque el sistema estaba inactivo.