Cómo progtwigr para correr el primer domingo de cada mes

Estoy usando Bash en RedHat. Necesito progtwigr un trabajo cron para que se ejecute a las 9:00 a.m. el primer domingo de cada mes. ¿Cómo puedo hacer esto?

Puede poner algo como esto en el archivo crontab :

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

La date +%d le da el número del día actual, y luego puede verificar si el día es menor o igual a 7. Si es así, ejecute su comando.

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

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

Necesita 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 comienzo de once_a_week , calcule la fecha y extraiga el día del mes mediante shell, Python, C / C ++, … y pruebe que está entre 1 y 7, inclusive. Si es así, ejecuta la secuencia de comandos real; si no, salga silenciosamente.

Una solución hacky: haga que su trabajo cron se ejecute todos los domingos, pero haga que el script verifique la fecha cuando se inicia y salga de inmediato si el día del mes es> 7 …

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

FALLARÁ en comandline debido al tratamiento especial de “%” en crontab (también válido para https://stackoverflow.com/a/3242169/2919695 )

Ejecuta una tarea cron 1er lunes, 3er martes, último domingo, cualquier cosa …

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

Simplemente coloque 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 script run-if-today solo devolverá 0 (valor bash para True) si es la fecha correcta.

EDITAR:

Ahora con una interfaz más simple, solo un parámetro para el número de 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 

Vale la pena señalar que lo que parece ser el enfoque más obvio para este problema no funciona.

Podría pensar que podría simplemente escribir una entrada de crontab que especifique el día de la semana como 0 (para el domingo) y el día del mes como 1-7, como este …

 # This does NOT work. 0 9 1-7 * 0 /path/to/your/script 

… pero, debido a la excentricidad de cómo Cron maneja las líneas de crontab con un día de la semana y un día del mes especificado , esto no funcionará, y de hecho se ejecutará en el 1.º, 2.º, 3.º, 4º, 5º, 6º y 7º del mes (independientemente del día de la semana) y todos los domingos del mes.

Esta es la razón por la que ve la recomendación de usar un [ ... ] cheque con date para configurar una regla como esta, ya sea especificando el día de la semana en el crontab y usando [ y la date para verificar que el día de la … month es <= 7 antes de ejecutar el script, como se muestra en la respuesta aceptada , o especificando el rango del día del crontab y utilizando [ y date para verificar el día de la semana antes de ejecutar, de esta manera:

 # This DOES work. 0 9 1-7 * * [ $(date +\%u) = 7 ] && /path/to/your/script 

Algunas prácticas recomendadas que debe tener en cuenta si desea asegurarse de que su línea de crontab funcione independientemente del sistema operativo en el que la utilice:

  • Use = , not == , para la comparación. Es más portátil, ya que no todos los shells usan una implementación de [ que admite el operador == .
  • Use el especificador %u hasta la date para obtener el día de la semana como un número, no como el operador %a , porque %a arroja resultados diferentes según la date configuración regional en que se esté ejecutando.
  • Simplemente use date , not /bin/date o /usr/bin/date , ya que la utilidad de date tiene diferentes ubicaciones en diferentes sistemas.

tal vez use cron.hourly para llamar a otro script. Ese script verificará si es el primer domingo del mes y las 9 a.m., y si es así, ejecutará su progtwig. Suena lo suficientemente óptimo para mí :-).

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 progtwigrse 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 … sin verificación de errores):

 #! /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 de encontrar el próximo 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 usé "at". No sé si eso es hacer trampa. La idea principal es encontrar el próximo primer domingo. Puede sustituir el progtwigdor 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 syntax diferente para la fecha).

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

todos los domingos de los primeros 7 días del mes