¿Puedo ejecutar un trabajo cron con más frecuencia que cada minuto?

44

¿Es posible ejecutar un trabajo cron cada 30 segundos sin un comando de suspensión?

usuario15336
fuente
44
¿Cual es tu intencion? ¿Es cron la herramienta adecuada para esto?
Manuel Faux el
Buena pregunta.
Saluda a Sangha el
Por ejemplo, actualmente estoy usando cron para cambiar la imagen de fondo de mi escritorio, para eludir las limitaciones del conmutador de imagen de fondo nativo (no sumergirme en subdirectorios). Si quisiera cambiar más de una vez por minuto, me encontraría con esta limitación cron. (aunque el conmutador bg nativo tiene la misma limitación)
donquixote

Respuestas:

36

Si su tarea necesita ejecutarse con esa frecuencia, cron es la herramienta incorrecta. Además del hecho de que simplemente no lanzará trabajos con tanta frecuencia, también corre el riesgo de tener problemas serios si el trabajo tarda más en ejecutarse que el intervalo entre lanzamientos. Vuelva a escribir su tarea para demonizar y ejecutar de forma persistente, luego iníciela desde cron si es necesario (asegurándose de que no se reinicie si ya se está ejecutando).

al anochecer
fuente
18
La parte "también corre el riesgo de tener problemas serios si el trabajo tarda más en ejecutarse que el intervalo entre lanzamientos". no es cierto y si lo fuera, se aplicaría igualmente a los trabajos que se ejecutan cada 5 minutos, cada hora o cada mes. Ese problema tiene soluciones (usar un archivo pid o lo que sea y verificar si el trabajo ya se está ejecutando antes de ejecutarlo). Entonces, el problema es que cron simplemente no permitirá esa frecuencia, pero es incorrecto decir que hay algo intrínsecamente incorrecto en la ejecución de una tarea cada menos de un minuto.
matteo
2
Me refiero a si no usas un archivo pid. Si su trabajo se ejecuta cada X minutos y tarda más de X minutos en terminar, terminará con trabajos apilándose. Si su trabajo también está limitado por algún tipo de recurso (CPU, ancho de banda de red / disco, etc.), ejecutar más a la vez hará que tarde más en terminar, y finalmente su computadora se convertirá en un desastre.
duskwuff
2
Puede usar run-onepara asegurarse de que un programa / incluso un script PHP no esté iniciando una instancia duplicada. sudo apt-get install run-oney llámalo porrun-one <normal command>
kouton
3
Como muestran las respuestas más abajo, es muy posible, aunque un poco hack. ¿Por qué lo estás haciendo mal? ¿La respuesta aceptada aquí, cuando no responde a la pregunta?
Alguien
@Mantriur ¿Porque el autor de la pregunta lo encontró útil y lo marcó como la respuesta aceptada? :) Pero en serio, sin embargo, ya has identificado el problema tú mismo: muchas de las otras respuestas contemporáneas propusieron soluciones piratas que no sería prudente usar en un sistema de producción. (Además, tenga en cuenta que varias de las otras respuestas solo aparecieron años después de que se hizo la pregunta, ¡así que aún no estaban disponibles para aceptarlas!)
duskwuff
37

Candidato para el mal uso más creativo de un comando de Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

Si yourprogconsiste en:

date +%M.%S.%N >> yourprog.out

entonces yourprog.outpodría verse así:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

indicando un muy buen nivel de precisión.

Aquí hay una explicación de las partes del comando:

  • nohup- Esto evita que el comando que le sigue, watchen este caso, salga cuando el terminal salga.
  • watch- Este programa ejecuta un comando repetidamente. Normalmente, la primera pantalla llena de resultados del comando se muestra cada vez que se watchejecuta el comando.
  • -n 30- El intervalo para ejecutar el comando. En este caso es cada treinta segundos.
  • --precise- Sin esta opción, watchejecuta el comando después de un intervalo de segundos. Con él, cada inicio del comando comienza en el intervalo si es posible. Si esta opción no se especificara en el ejemplo, los tiempos llegarían más tarde y más tarde en más de 30 segundos cada vez debido al tiempo que lleva iniciar y ejecutar el comando ( yourprog).
  • yourprog- El programa o línea de comando para watchejecutar. Si la línea de comando contiene caracteres especiales para el shell (por ejemplo, espacio o punto y coma), será necesario citarlo.
  • >/dev/null- El mayor que vuelve a dirigir la salida del comando que se ejecuta mediante watchun archivo, /dev/null. Ese archivo descarta cualquier dato escrito en él. Esto evita que la salida se escriba en la pantalla o, dado que nohupse está utilizando, evita que la salida se envíe a un archivo llamado nohup.out.
  • &- El watchcomando se ejecuta en segundo plano y el control se devuelve al terminal o proceso principal.

Tenga en cuenta que nohupla redirección de salida y el &operador de control de fondo no son específicos de watch.

Aquí hay una explicación del yourprogscript de ejemplo :

  • date- Emite la fecha y / o hora actual. También puede configurarlos.
  • +%M.%S.%N- Esto especifica el formato de salida para dateusar. %Mes el minuto actual, %Ses el segundo actual y %Nes el nanosegundo actual.
  • >> yourprog.out- Esto redirige la salida del datecomando a un archivo llamado yourprog.out. El doble mayor que hace que la salida se agregue al archivo en cada invocación en lugar de que se sobrescriban los contenidos anteriores.

Editar :

Posiblemente otra cosa que podría abusarse (o tal vez sea un uso legítimo) son los temporizadores systemd.

Ver systemd / Timers como un reemplazo de cron y Cron vs temporizadores systemd .

Intentaré publicar un ejemplo pronto.

Pausado hasta nuevo aviso.
fuente
66
Estoy dando +1 por pura mejilla
Matt Simmons
2
Sería bueno tener un poco más de explicación con esta respuesta. El comando nohup es nuevo para mí. Internet me dice que es ignorar la señal de colgar. Lo que todavía me deja confundido.
donquixote
2
@donquixote: Es importante reconocer que el comando en su conjunto en mi respuesta no es una cosa recomendada, de ahí el uso de la palabra "mal uso". Sin embargo, para aclararle un poco las cosas, ya que se incluyen técnicas útiles, intentaré describir algunas. Esto &hace que el comando se ejecute en segundo plano, devolviendo el control al símbolo del sistema inmediatamente. El uso del nohupcomando hace que el proceso en segundo plano (en este caso watch) ignore la señal de bloqueo que se envía cuando sale el shell, como cuando cierra el terminal. ...
Pausado hasta nuevo aviso.
1
... Redirigir la salida usando >/dev/nullhace que la salida se descarte y evita la creación de un nohup.outarchivo que de otro modo se crearía cuando la salida estándar es un terminal.
Pausado hasta nuevo aviso.
1
@donquixote: No solo 30 segundos a partir de ahora, cada 30 segundos. El resto es hacer que se ejecute sin supervisión en segundo plano para que sea más parecido a un cron. Si quisiera usarlo sleep, necesitaría escribir un ciclo para que el proceso se repita ( watchesto se repite para usted, al igual que cron). Aún necesitarías nohupy &. Un problema adicional con sleepsería la deriva del tiempo. La --preciseopción de watchevita esto. Sin él o cuando se usa sleepen un bucle, el intervalo de tiempo tiene el tiempo que tardan los comandos o la secuencia de comandos en agregarse, por lo que cada ejecución se hace más tarde y más tarde que ...
Pausado hasta nuevo aviso.
13

Cron está diseñado para despertarse a cada minuto, por lo que no es posible hacerlo sin algún hackeo, por ejemplo, dormir como usted mencionó.

Balázs Pozsár
fuente
10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

No olvides escribir algo en tu programa para que salga si ya se está ejecutando una instancia anterior.

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

Por supuesto, esto todavía deja una oportunidad muy pequeña para el fracaso, así que busque en Google una mejor solución aplicable a su entorno.

ghoti
fuente
se le ha preguntado:without a sleep command
philippe
10
A otros visitantes que encuentren esta pregunta no les importa si se usa el comando de suspensión :)
donquixote
8

Puede hacer esto con software de terceros.

Una opción que me ha funcionado bien es frecuente-cron

Permite una precisión de milisegundos y le da la opción de diferir la próxima ejecución hasta que la actual haya salido.

thatjuan
fuente
1
Frecuente-cron también ha funcionado bien para nosotros y potencia muchos de nuestros sistemas de producción. Nunca hemos tenido un problema con eso.
Homer6
2

Tendría un par de preocupaciones:

(1) a veces un sistema se llena y no puede comenzar las cosas exactamente en el punto de 30 segundos, entonces es posible que al mismo tiempo que esté ejecutando un trabajo aparezca otro trabajo y luego tenga 2 (o más) trabajos haciendo lo mismo cosa. Dependiendo del guión, puede haber alguna interferencia significativa aquí. Por lo tanto, la codificación en un script de este tipo debe contener algún código para garantizar que solo se ejecute una instancia del script al mismo tiempo.

(2) La secuencia de comandos podría tener muchos gastos generales y consumir más recursos del sistema de los que podría desear. Esto es cierto si compite contra muchas otras actividades del sistema.

Por lo tanto, como lo expresó un afiche, en este caso consideraría seriamente poner en ejecución un demonio con procesos adicionales para garantizar que siga ejecutándose si es de importancia crítica para sus operaciones.

mdpc
fuente
1

Mi solución más simple y favorita para esta tarea:

entrada cron:
* * * * * flock -w0 /path/to/script /path/to/script

guión:
while true;do echo doing something; sleep 10s;done

alternativa perezosa: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

o

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

pros

  • El uso del flockcomando evita ejecutar el script en varias instancias al mismo tiempo. Puede ser muy importante en la mayoría de los casos.
  • flocky los watchcomandos están disponibles en la mayoría de las instalaciones de Linux

contras

  • detener este tipo de "Servicio" necesita dos pasos
    • comentar la entrada cron
    • matar el guión o el watchcomando
asvany
fuente
2
¿Alguien puede explicar esto a un novato de Linux, con pros y contras? Gracias ..
a20
@asvany Creo que me gusta esta solución, pero como a20, ¿podría publicar alguna explicación para el "verde" de Linux, por favor? ty.
JoelAZ
0

Una solución, si es para su propio script o si puede envolverlo:

  1. Obtenga y recuerde la hora de inicio.
  2. Si hay un archivo de bloqueo, que tocará más tarde, y el script no se ha ejecutado durante 60 segundos, espere un segundo y verifique nuevamente. (por ejemplo, mientras / dormir) *
  3. Si el archivo de bloqueo sigue presente después de transcurridos 60 segundos, salga con una advertencia de bloqueo obsoleto.
  4. Toque bloquear archivo.
  5. Si bien el script no se ha ejecutado durante 60 segundos, repita su tarea real con la duración de suspensión deseada.
  6. Eliminar archivo de bloqueo.
  7. Añadir como minutamente cron.
  8. Bob es tu tio.

Menos dolor de cabeza que construir y monitorear un demonio.

* Si está utilizando PHP, recuerde clearstatcache ().

Alguien
fuente