bash - instalar - ejecutar crontab manualmente
Trabajos de cron y tiempos aleatorios, dentro de horas determinadas (8)
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
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.
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 programados 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.
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.
Sí, sí, la pregunta tiene más de un año, pero tal vez pueda agregar algo útil:
¿Cómo programar 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.
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.
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 programados, 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.