¿31 implica necesariamente el fin de mes en un trabajo cron?

13

Para el trabajo cron, sabemos que podemos establecer el tiempo de la siguiente manera.

# +------------ Minute (0 - 59)
# | +---------- Hour (0 - 23)
# | | +-------- Day of the Month (1 - 31)
# | | | +------ Month (1 - 12)
# | | | | +---- Day of the Week (0 - 7) (Sunday is 0 or 7)
# | | | | |
# * * * * * command

Lo que quiero saber es que cuando establecemos el día del mes 31, esto significa el final de cada mes, aunque el mes no tiene el día 31. Espero obtener una respuesta.

Gracias por adelantado

squillman
fuente

Respuestas:

22

No, 31 significa 31.

Sin embargo, puedes hacer algunos trucos. Configure el trabajo para que se ejecute en cualquier día que podría ser el último día del mes (es decir, 28-31 en el campo del día del mes), y luego reemplace su comando con una expresión de shell que comprende una prueba en la fecha que protege el mando:

0 0 28-31 * * [ "`date +%m`" != "`date --date=tomorrow +%m`" ] && command

La expresión dentro de los corchetes de prueba solo pregunta si el número de mes de hoy es diferente al número de mes de mañana, lo que por supuesto solo será cierto el último día del mes. Tenga en cuenta que la forma de esta expresión depende de su local date; es posible que deba modificarla si no tiene la versión actual de GNU.

Debo decir que no inventé esto: lo encontré con un Google rápido en una publicación de la lista de correo de Matthew Jarvis. Sin embargo, me imagino que este es en gran medida un viejo truco estándar de Unix Wizard.

Tom Anderson
fuente
1
No puede ser un truco demasiado antiguo dadas las opciones específicas de GNU para "date" =)
jj33
44
En los sitios de stackexchange, hacer una pregunta que se pueda responder con una búsqueda en Google, NO es algo malo. De hecho, es algo bueno, ya que la próxima persona que busque esto en Google encontrará la respuesta en stackexchange y vendrá aquí.
miernik
12

No, creo que lo mejor que puedes hacer es correr a medianoche el 1 de cada mes, o configurar líneas de crontab individuales para cada mes (o al menos, una línea para meses con 28,29,30 y 31 días)

0 0 28,29 2               * /my/command
0 0 30    4,6,9,11        * /my/command
0 0 31    1,3,5,7,8,10,12 * /my/command
Paul Dixon
fuente
Gracias paul! Seguiré el segundo. Para el segundo método, ¿necesito configurar el mismo archivo tres veces, ¿verdad? Gracias de nuevo :)
Sí, deberás repetirlo.
Paul Dixon
77
No tengo experiencia con cron, pero ¿"0 0 28,29 2" no se ejecutaría dos veces en un año bisiesto? No es que esto sería un problema para los próximos dos años, pero aún así ...
Wim ten Brink
Ese es un buen punto, no hay manera fácil de evitar que
Paul Dixon
4

No creo que puedas hacer esto fácilmente en el crontab.

Una opción sería configurar cronpara ejecutar el script todos los días y luego hacer que el script compruebe si es el último día del mes.

Dave Webb
fuente
3

Supongo que cron tiene un carácter especial 'L' para este propósito:

*    *    L    *    *    your_script.sh 

ejecutaría su script el último día de cada mes

Por otra parte,

*    *    0    *    *    your_script.sh

Incluso puede especificar algo como:

*    *    *    *    1,5L    your_scrript.sh

ejecutar el script el último lunes y viernes de cada mes

o

*    *    *    *    1    your_script.sh

ejecutar el script todos los lunes a la medianoche.

Saasira
fuente
0

Esto hará el trabajo:

if [ $( date +%-d --date="tomorrow" ) -eq 1 ]
then echo Last day of the current month
else echo Not yet!
     exit 0
fi

exit 1
Phil
fuente