2010-07-13 102 views
41

Estoy usando Bash en RedHat. Necesito programar un trabajo cron para que se ejecute a las 9:00 a.m. el primer domingo de cada mes. Hice una pequeña investigación y veo que no hay una mano corta en cron para esto.Cómo programar para ejecutar el primer domingo de cada mes

¿Conoces una manera óptima?

+3

Es posible obtener resultados publicar esta pregunta en serverfault.com. –

Respuesta

113

Usted puede poner algo así en el archivo crontab:

00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script 

El date +%d le da el número del día en curso, y luego se puede comprobar si el día es menor o igual a 7. Si es, ejecuta tu comando.

Si ejecuta esta secuencia de comandos solo los domingos, debería significar que solo se ejecuta el primer domingo del mes.

Recuerde que en el archivo crontab, deben escaparse las opciones de formato para el comando date.

+2

esta es una excelente solución. usted no tiene que editar su programa, solo puede hacer este truco en la entrada de cron y lograr el requisito. – thegeek

+1

esta debería ser la mejor respuesta. – clopez

+0

esto es brillante ¿dónde está documentada esta '-le'? Necesito hacer lo mismo para el primer domingo, el segundo domingo, el tercer domingo, el cuarto domingo y (tal vez) el 5º domingo ... –

1

utilice cron.hourly para llamar a otra secuencia de comandos. Ese script verificará si es el primer domingo del mes y las 9 a.m., y si es así, ejecutará su programa. Suena lo suficientemente óptimo para mí :-).

+4

Excepto que es mejor llamarlo a diario: es un hecho poco conocido que el día cambia una vez al día. ;) – Isaac

+0

dijo 9am aunque – gtrak

+0

Gracias por su respuesta Aunque no es un gran problema, ¿por qué ejecutar un script cada hora? Estoy buscando un script semanal para ejecutar todos los domingos. Pero preguntándose si alguien ya hizo algo similar. –

6

Una solución hacky: tener su trabajo cron ejecutar todos los domingos, sino que tenga la secuencia de comandos comprobar la fecha, ya que comienza, y salir de inmediato si el día del mes es> 7 ...

+0

Sí, acabo de sugerir lo mismo. No estoy seguro de por qué se votó en contra de eso ... –

+0

Suena bien - Elegí una respuesta más descriptiva. –

+0

Admito que los puntos deberían ir a la respuesta más completa. Me alegro de haber perdido mi Voto: D – thesunneversets

12

es necesario combinar dos enfoques:

a) Use cron para ejecutar un trabajo todos los domingos a las 9:00 a.m.

00 09 * * 7  /usr/local/bin/once_a_week 

b) Al principio de once_a_week, calcular la fecha y extraer el día del mes a través de la cáscara, Python, C/C++, ... y la prueba de que está dentro de 1 a 7, inclusive. Si es así, ejecuta la secuencia de comandos real; si no, salga silenciosamente.

+1

Ambos funcionan como 'man 5 crontab' dice esto al respecto' día de la semana 0-7 (0 o 7 es Sun, o nombres de uso) ' –

+1

Su derecho, había comprobado el hombre crontab (que no dice mucho) pero no man 5 crontab, que dice que tanto el 0 como el 7 se cuentan como el domingo. –

1

Si no desea que cron ejecute su trabajo todos los días o todos los domingos, puede escribir un contenedor que ejecute su código, determinar el próximo primer domingo y programarse para ejecutarse en esa fecha.

Luego programe esa envoltura para el próximo primer domingo del mes. Después de eso manejará todo por sí mismo.

El código sería algo así como (énfasis en algo ... hay chequeos de errores se hace):

#! /bin/bash 
#We run your code first 
/path/to/your/code 
#now we find the next day we want to run 
nskip=28 #the number of days we want to check into the future 
curr_month=`date +"%m"` 
new_month=`date --date='$nskip days' +"%m"` 
if [[ curr_month = new_month ]] 
then 
((nskip+=7)) 
fi 
date=`date --date='$nskip days' +"09:00AM %D` #you may need to change the format if you use another scheduler 
#schedule the job using "at" 
at -m $date < /path/to/wrapper/code 

La lógica es simple para encontrar el siguiente primer domingo. Dado que comenzamos el primer domingo del mes actual, agregar 28 nos pondrá el último domingo del mes actual o el primer domingo del mes siguiente. Si es el mes actual, aumentamos hasta el próximo domingo (que será la primera semana del mes siguiente).

Y utilicé "at". No sé si eso es hacer trampa. La idea principal es encontrar el próximo primer domingo. Puede sustituir el programador que desee después de eso, ya que sabe la fecha y la hora en que desea ejecutar el trabajo (sin embargo, un planificador diferente puede necesitar una sintaxis diferente para la fecha).

-2

00 09 1-7 * 0/usr/local/bin/once_a_week

todos los domingos de 7 primeros días del mes

+6

Disculpa, esta funcionará todos los domingos Y los primeros 7 días del mes. Vea aquí: http://stackoverflow.com/a/6203414/327064 – ak112358

5

Esto también funciona con los nombres de los días de la semana:

0 0 1-7 * * [ "$(date '+\%a')" == "Sun" ] && /usr/local/bin/urscript.sh 

Pero,

[ "$(date '+\%a')" == "Sun" ] && echo SUNDAY

voluntad FALLO en comandline debido al tratamiento especial de "%" en el crontab (también válido para https://stackoverflow.com/a/3242169/2919695)

+1

Esto es similar al anterior pero me gusta más para la legibilidad. –

+0

esta debería ser la respuesta correcta, lo que diría es que la segunda parte de la respuesta de maniac_ dice: "pero ... fallará", todo lo que quiere decir es que fallará en CMD en BASH pero NO fallará si es un crontab –

5

ejecutar una tarea de cron primera Lunes, Martes tercero, el domingo pasado, nada ..

http://xr09.github.io/cron-last-sunday/

Simplemente ponga el script run-if-today en la ruta y úselo con cron.

30 6 * * 6 root run-if-today 1 Sat && /root/myfirstsaturdaybackup.sh 

El guión run-if-today sólo devolverá 0 (valor de bash para True) si es la fecha correcta.

EDIT:

Ahora con interfaz más simple, un solo parámetro de número de la semana.

# run every first saturday 
30 6 * * 6 root run-if-today 1 && /root/myfirstsaturdaybackup.sh 

# run every last sunday 
30 6 * * 7 root run-if-today L && /root/lastsunday.sh 
+1

Hope funciona, porque estoy confiando en él ahora :) – Dennis

+0

@Dennis Ve por ello, cualquier problema solo informa un nuevo problema. Me alegro de que ayude. :) –

Cuestiones relacionadas