Trabajo cron cada tres días

93

¿Es posible ejecutar un cronjob cada tres días? O quizás 10 veces al mes.

tmartin314
fuente
4
Sí, es posible y esto pertenece a SuperUser.
La ejecución cada 3 días, independientemente de los límites de los meses, se puede realizar con anacron.
ryanpattison

Respuestas:

125

Ejecútelo cada tres días ...

0 0 */3 * *

¿Qué hay sobre eso?

Si desea que se ejecute en días específicos del mes, como el 1, 4, 7, etc., puede tener un condicional en su script que verifique el día actual del mes.

if (((date('j') - 1) % 3))
   exit();

o, como señala @mario, puede usar date ('k') para obtener el día del año en lugar de hacerlo basándose en el día del mes.

arándano
fuente
9
@whatshakin: Dependerá de qué tan preciso quieras que sea "cada tres días". Esto funcionará en cualquier día que sea divisible por 3. En los límites de los meses no será exacto.
David
3
@whatshakin: La sintaxis de cronjob incluso se describe en Wikipedia: en.wikipedia.org/wiki/Cronjob
Felix Kling
4
Este es un resultado muy alto en Google y, como tal, sería mejor si la respuesta aceptada fuera correcta, lo que no es así. Creo que la explicación de Tareco es correcta.
Lynks
14
La respuesta no es correcta porque ninguna de las sugerencias ejecuta el trabajo cada 3 días. 0 0 */3 * *significa ejecutar el 1, 4, 7, etc. ( */3significa 1-31/3significa 1,4,7...31) por lo que la brecha será menor al final del mes. (Se ejecutará 2 días seguidos si el mes anterior tuvo 31 días). date('j') % 3Tiene un problema similar en el sentido de que el patrón se reinicia todos los años y los años no tienen un número de días divisible por 3.
cjm
8
Yo también considero desafortunado que esto fuera aceptado como la respuesta. Realmente estaba buscando cada N días, independientemente de los límites del mes (a cosas como a las plantas no les importa qué día del mes obtienen su agua). Al menos creo que determiné después de leer todos los comentarios, que el cronómetro por sí solo no modela completamente ese deseo.
Travis Griggs
69
* * */3 * *  that says, every minute of every hour on every three days. 

0 0 */3 * *  says at 00:00 (midnight) every three days.
tareco
fuente
aprecio la explicación
pythonian29033
2
Esto generalmente se activará cada tres días, pero puede
activarse
24

No soy un especialista en cron, pero qué tal:

0 */72 * * *

Funcionará cada 72 horas sin interrupciones.

https://crontab.guru/#0_ / 72_ _ _

Fabio Nolasco
fuente
3
Esto es más preciso que la solución aceptada. La respuesta aceptada fallará al cambiar de mes:then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Akira Yamamoto
¿Cómo se calcula cuándo ocurrirá esto?
Bruce Edge
2
Según crontab.guru, esto se ejecuta todos los días. Quien tiene razon
velop
1
El valor en la columna de la hora debe estar entre 0 y 23 según crontab.guru y man crontab .
harperville
1
* / 72 es efectivamente lo mismo que 0. Se ejecuta cada medianoche.
Battey
19

Debido a que cron es "sin estado", no puede expresar con precisión "frecuencias", solo "patrones" que (aparentemente) compara continuamente con la hora actual.

Reformular su pregunta hace que esto sea más obvio: "¿es posible ejecutar un cronjob a las 00:01 am todas las noches, excepto omitir noches en las que se ejecutó en 2 noches?" Cuando cron compara la hora actual con los patrones de tiempo de solicitud de trabajo, no hay forma de que cron pueda saber si ejecutó su trabajo en el pasado.

Por lo general, debe terminar ese evento recurrente y reiniciar uno completamente nuevo; esto ilustra la expresividad limitada de cómo incluso las aplicaciones de calendario complicadas representan patrones repetidos. Y, por supuesto, los calendarios tienen muchos estados: cada evento individual se puede eliminar o reprogramar de forma independiente [en la mayoría de las aplicaciones de calendario]).

Además, probablemente desee hacer su trabajo cada 3 noches si tiene éxito , pero si la última falló, vuelva a intentarlo de inmediato, tal vez la noche siguiente (no espere 3 días más) o incluso antes, como una hora después (pero deje de intentarlo de nuevo). a la llegada de la mañana). Claramente, cron no podría saber si su trabajo tuvo éxito y el patrón tampoco puede expresar un programa alternativo de "reintentos" más frecuentes.

DE TODAS FORMAS-- Puedes hacer lo que quieras tú mismo. Escriba un script, dígale a cron que lo ejecute todas las noches a las 00:01 am. Este script puede verificar la marca de tiempo de algo * que registra la "última ejecución", y si fue hace> 3 días **, realizar el trabajo y restablecer la marca de tiempo de la "última ejecución".

(* ese indicador con marca de tiempo es un poco de estado persistente que puede manipular y examinar, pero que cron no puede)

** tenga cuidado con la aritmética del tiempo si está usando un reloj legible por humanos: dos veces al año, algunos días tienen 23 o 25 horas en su día, y 02: 00-02: 59 ocurre dos veces en un día o no en todas. Utilice UTC para evitar esto.

Jaime guerrero
fuente
7
0 0 1-30/3 * *

Esto se ejecutará cada tres días a partir del primero. Aquí están las 20 ejecuciones programadas:

  • 2015-06-01 00:00:00
  • 2015-06-04 00:00:00
  • 2015-06-07 00:00:00
  • 2015-06-10 00:00:00
  • 2015-06-13 00:00:00
  • 2015-06-16 00:00:00
  • 2015-06-19 00:00:00
  • 2015-06-22 00:00:00
  • 2015-06-25 00:00:00
  • 2015-06-28 00:00:00
  • 2015-07-01 00:00:00
  • 2015-07-04 00:00:00
  • 2015-07-07 00:00:00
  • 2015-07-10 00:00:00
  • 2015-07-13 00:00:00
  • 2015-07-16 00:00:00
  • 2015-07-19 00:00:00
  • 2015-07-22 00:00:00
  • 2015-07-25 00:00:00
  • 2015-07-28 00:00:00
Vishal
fuente
5
2015-07-31 00:00:00, 2015-08-01 00:00:00 ... OOPS solo 1 día entre carreras
Dziamid
4

No creo que tengas lo que necesitas con:

0 0 */3 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!

Desafortunadamente, el * / 3 establece el intervalo cada n días del mes y no cada n días . Ver: explicación aquí . A fin de mes hay emisión recurrente garantizada.

1st  at 2019-02-01 00:00:00
then at 2019-02-04 00:00:00 << 3 days, etc. OK
then at 2019-02-07 00:00:00
...
then at 2019-02-25 00:00:00
then at 2019-01-28 00:00:00
then at 2019-03-01 00:00:00 << 1 day WRONG
then at 2019-03-04 00:00:00
...

De acuerdo con este artículo , debe agregar algunos módulos matemáticos al comando que se está ejecutando para obtener un VERDADERO "cada N días". Por ejemplo:

0 0 * * *  bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh

En este ejemplo, el trabajo se comprobará diariamente a las 12:00 a. M., Pero solo se ejecutará cuando el número de días desde el 01-01-1970 módulo 3 sea 0.

Si desea que sea cada 3 días a partir de una fecha específica, use el siguiente formato:

0 0 * * *  bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 3 == 0 )) && runmyjob.sh
Brad Cozine
fuente
3

Qué tal si:

00 00  *  *   * every 3 days && echo test

Dónde everyestá un guión:

#!/bin/sh

case $2 in
    days)
        expr `date +%j` % $1 = 0 > /dev/null
        ;;

    weeks)
        expr `date +%V` % $1 = 0 > /dev/null
        ;;

    months)
        expr `date +%m` % $1 = 0 > /dev/null
        ;;
esac

Entonces funciona todos los días.

El uso se */3ejecuta los días 3, 6, ... 27, 30 del mes, pero luego es incorrecto después de que un mes tiene 31 días. El everyguión solo está mal después de fin de año.

MattBlissett
fuente
3

Deberías aprender los conceptos básicos de crontab.

Edite el cron por comando crontab -ey luego ⌃ (CTRL)+ Xluego Yy finalmente presione ENTER (return)en mac para guardar el archivo. Puede comprobar que los nuevos crones se han instalado no porcrontab -l

Un archivo crontab tiene cinco campos para especificar minutos, horas, día del mes, mes y día de la semana seguidos del comando que se ejecutará en ese intervalo.

*     *     *   *    *   command to be executed
-     -     -   -    -
|     |     |   |    |
|     |     |   |    +----- day of week (0-6) (Sunday=0)
|     |     |   +------- month (1-12)
|     |     +--------- day of month (1-31)
|     +----------- hour (0-23)
+------------- min (0-59)

* en el campo de valor anterior significa todos los valores legales entre llaves para esa columna.

Aquí, escribí una publicación detallada al respecto: Configurar Cron en Unix

Ahmad Awais
fuente
1

Sería más sencillo si lo configurara para que se ejecute, por ejemplo, los lunes y jueves, lo que le daría un descanso de 3 y 4 días.

De lo contrario, configúrelo para que se ejecute a diario, pero haga que su secuencia de comandos cron php salga temprano con:

if (! (date("z") % 3)) {
     exit;
}
mario
fuente
0

Si desea que se ejecute en días específicos del mes, como el 1, 4, 7, etc., puede tener un condicional en su script que verifique el día actual del mes.

Pensé que todo lo que necesitabas para esto era en lugar de * / 3, lo que significa que cada tres días, usa 1/3, lo que significa que cada tres días a partir del día 1 del mes. por lo que 7/3 significaría cada tres días a partir del día 7 del mes, etc.

Colin Hilbert
fuente
0

0 0 * * * [ $(($((fecha +% - j- 1)) % 3)) == 0 ] && script

Obtenga el día del año desde date, compensado por 1 para comenzar en 0, verifique si es módulo tres.

Curtidor
fuente
¿No tendrá este contratiempo cuando pase de un año no bisiesto al año siguiente, desde ( 365-1 ) % 3 == 1pero ( 1 - 1 ) % 3 == 0? Creo que el mejor cálculo se basaría en el número de días desde la época de Unix.
kmoser