Programaci贸n de trabajos con python-crontab

    驴Qu茅 es Crontab?

    Cron es una utilidad de software que nos permite programar tareas en sistemas similares a Unix. El nombre se deriva de la palabra griega “Chronos”, que significa “tiempo”.

    Las tareas en Cron se definen en un crontab, que es un archivo de texto que contiene los comandos a ejecutar. La sintaxis utilizada en un crontab se describe a continuaci贸n en este art铆culo.

    Python nos presenta el m贸dulo crontab para administrar trabajos programados a trav茅s de Cron. Las funciones disponibles en 茅l nos permiten acceder a Cron, crear trabajos, establecer restricciones, eliminar trabajos y m谩s. En este art铆culo mostraremos c贸mo usar estas operaciones desde dentro de su c贸digo Python.

    Para el lector interesado, la p谩gina de ayuda oficial se puede encontrar en https://pypi.python.org/pypi/python-crontab.

    Sintaxis de Crontab

    Cron usa una sintaxis espec铆fica para definir los horarios. Consta de cinco campos, que est谩n separados por espacios en blanco. Los campos son:

    Minute Hour Day Month Day_of_the_Week
    

    Los campos pueden tener los siguientes valores:

    鈹屸攢鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹 minute (0 - 59)
    鈹 鈹屸攢鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹 hour (0 - 23) 
    鈹 鈹 鈹屸攢鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹 day of month (1 - 31)
    鈹 鈹 鈹 鈹屸攢鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹 month (1 - 12)
    鈹 鈹 鈹 鈹 鈹屸攢鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹鈹 day of week (0 - 6) (Sunday to Saturday;
    鈹 鈹 鈹 鈹 鈹                                       7 is also Sunday on some systems)
    鈹 鈹 鈹 鈹 鈹
    鈹 鈹 鈹 鈹 鈹
    * * * * *  command to execute
    

    Fuente: Wikipedia. Cron. Disponible en https://en.wikipedia.org/wiki/Cron

    Cron tambi茅n acepta caracteres especiales para que pueda crear horarios m谩s complejos. Los caracteres especiales tienen los siguientes significados:

    Significado del personaje

    ComaPara separar varios valores
    Gui贸nPara indicar un rango de valores
    AsteriscoPara indicar todos los valores posibles
    Barra inclinadaPara indicar CADA

    Veamos algunos ejemplos:

    • * * * * * significa: cada minuto de cada hora de cada d铆a del mes para cada mes para cada d铆a de la semana.
    • 0 16 1,10,22 * * le dice a cron que ejecute una tarea a las 4 PM (que es la hora 16) los d铆as 1, 10 y 22 de cada mes.

    Instalaci贸n de Crontab

    Crontab no est谩 incluido en la instalaci贸n est谩ndar de Python. As铆, lo primero que tenemos que hacer es instalarlo.

    Esto se hace con el pip mando. Lo 煤nico a considerar es que el nombre del m贸dulo es ‘python-crontab’ y no solo ‘crontab’. El siguiente comando instalar谩 el paquete en nuestra m谩quina:

    $ pip install python-crontab
    

    Obtener acceso a Crontab

    Seg煤n la p谩gina de ayuda de crontab, hay cinco formas de incluir un trabajo en cron. De ellos, tres funcionan solo en Linux y dos tambi茅n se pueden usar en Windows.

    La primera forma de acceder a cron es usando el nombre de usuario. La sintaxis es la siguiente:

    cron = CronTab(user="username")
    

    Las otras dos formas de Linux son:

    cron = CronTab()
    
    # or
    
    cron = CronTab(user=True)
    

    Hay dos sintaxis m谩s que tambi茅n funcionar谩n en Windows.

    En el primero, llamamos a una tarea definida en el archivo “filename.tab”:

    cron = CronTab(tabfile="filename.tab")
    

    En el segundo, definimos la tarea seg煤n la sintaxis de Cron:

    cron = CronTab(tab="""* * * * * command""")
    

    Crear un trabajo nuevo

    Una vez que hayamos accedido a cron, podemos crear una nueva tarea usando el siguiente comando:

    cron.new(command='my command')
    

    Aqu铆, my command define la tarea que se ejecutar谩 a trav茅s de la l铆nea de comando.

    Tambi茅n podemos agregar un comentario a nuestra tarea. La sintaxis es la siguiente:

    cron.new(command='my command', comment="my comment")
    

    Veamos esto en un ejemplo:

    from crontab import CronTab
    
    cron = CronTab(user="username")
    job = cron.new(command='python example1.py')
    job.minute.every(1)
    
    cron.write()
    

    En el c贸digo anterior, primero accedimos a cron a trav茅s del nombre de usuario y luego creamos un trabajo que consiste en ejecutar un script de Python llamado example1.py. Adem谩s, hemos configurado la tarea para que se ejecute cada 1 minuto. los write() La funci贸n agrega nuestro trabajo a cron.

    El script example1.py es el siguiente:

    from datetime import datetime
    myFile = open('append.txt', 'a') 
    myFile.write('nAccessed on ' + str(datetime.now()))
    

    Como podemos ver en el c贸digo anterior, el programa se abrir谩 y agregar谩 la frase “Accedido el” con la fecha y hora de acceso agregadas.

    El resultado es el siguiente:

    Figura 1

    Como esper谩bamos, la Figura 1 muestra que el programa accedi贸 al archivo. Continuar谩 realizando la tarea asignada mientras el programa example1.py se est茅 ejecutando en cron.

    Una vez que se accede a cron, podemos agregar m谩s de un trabajo. Por ejemplo, la siguiente l铆nea en el ejemplo anterior agregar铆a una segunda tarea para ser administrada por cron:

    job2 = cron.new(command='python example2.py')
    

    Una vez que se agrega una nueva tarea, podemos establecer restricciones para cada una de ellas.

    Establecer restricciones

    Una de las principales ventajas de usar el m贸dulo crontab de Python es que podemos configurar restricciones de tiempo sin tener que usar la sintaxis de cron.

    En el ejemplo anterior, ya hemos visto c贸mo configurar la ejecuci贸n del trabajo cada minuto. La sintaxis es la siguiente:

    job.minute.every(minutes)
    

    Del mismo modo, podr铆amos configurar las horas:

    job.hour.every(hours)
    

    Tambi茅n podemos configurar la tarea para que se ejecute en determinados d铆as de la semana. Por ejemplo:

    job.dow.on('SUN')
    

    El c贸digo anterior le dir谩 a cron que ejecute la tarea los domingos, y el siguiente c贸digo le dir谩 a cron que programe la tarea los domingos y viernes:

    job.dow.on('SUN', 'FRI')
    

    De manera similar, podemos decirle a cron que ejecute la tarea en meses espec铆ficos. Por ejemplo:

    job.month.during('APR', 'NOV')
    

    Esto le dir谩 a cron que ejecute el programa en los meses de abril y noviembre.

    Una cosa importante a considerar es que cada vez que establecemos una restricci贸n de tiempo, anulamos la anterior. As铆, por ejemplo:

    job.hour.every(5)
    job.hour.every(7)
    

    El c贸digo anterior establecer谩 el programa final para que se ejecute cada siete horas, cancelando el programa anterior de cinco horas.

    A menos que agreguemos un horario a uno anterior, como este:

    job.hour.every(15)
    job.hour.also.on(3)
    

    Esto establecer谩 el horario cada 15 horas y a las 3 a. M.

    La condici贸n de ‘todos’ puede ser un poco confusa a veces. Si escribimos job.hour.every(15), esto ser谩 equivalente a * */15 * * *. Como vemos, el acta no se ha modificado.

    Si queremos poner el campo de minutos a cero, podemos usar la siguiente sintaxis:

    job.every(15).hours()
    

    Esto establecer谩 el horario en 0 */4 * * *. De manera similar para los campos ‘d铆a del mes’, ‘mes’ y ‘d铆a de la semana’.

    Ejemplos:

    • job.every(2).month es equivalente a 0 0 0 */2 * y job.month.every(2) es equivalente a * * * */2 *
    • job.every(2).dows es equivalente a 0 0 * * */2 y job.dows.every(2) es equivalente a * * * * */2

    Podemos ver las diferencias en el siguiente ejemplo:

    from crontab import CronTab
    
    cron = CronTab(user="username")
    
    job1 = cron.new(command='python example1.py')
    
    job1.hour.every(2)
    
    job2 = cron.new(command='python example1.py')
    job2.every(2).hours()
    
    for item in cron:
        print item
    
    cron.write()
    

    Despu茅s de ejecutar el programa, el resultado es el siguiente:

    $ python cron2.py
    * */2 * * * python /home/eca/cron/example1.py
    0 */2 * * * python /home/eca/cron/example1.py
    $
    

    Figura 2

    Como podemos ver en la Figura 2, el programa ha establecido los minutos de la segunda tarea en cero y ha definido los minutos de la primera tarea en su valor predeterminado.

    Finalmente, podemos configurar la tarea para que se ejecute cada vez que arrancamos nuestra m谩quina. La sintaxis es la siguiente:

    job.every_reboot()
    

    Restricciones de compensaci贸n

    Podemos borrar todas las restricciones de la tarea con el siguiente comando:

    job.clear()
    

    El siguiente c贸digo muestra c贸mo utilizar el comando anterior:

    from crontab import CronTab
    
    cron = CronTab(user="username")
    
    job = cron.new(command='python example1.py', comment="comment")
    job.minute.every(5)
    
    for item in cron:
        print item
    
    job.clear()
    
    for item in cron:
        print item
    cron.write()
    

    Despu茅s de ejecutar el c贸digo obtenemos el siguiente resultado:

    $ python cron3.py
    */5 * * * * python /home/eca/cron/example1.py # comment
    * * * * * python /home/eca/cron/example1.py # comment
    

    figura 3

    Como podemos ver en la Figura 3, el horario ha cambiado de cada 5 minutos a la configuraci贸n predeterminada.

    Habilitaci贸n y deshabilitaci贸n de un trabajo

    Una tarea se puede habilitar o deshabilitar usando los siguientes comandos:

    Para habilitar un trabajo:

    job.enable()
    

    Para deshabilitar un trabajo:

    job.enable(False)
    

    Para verificar si una tarea est谩 habilitada o deshabilitada, podemos usar el siguiente comando:

    job.is_enabled()
    

    El siguiente ejemplo muestra c贸mo habilitar y deshabilitar un trabajo creado previamente y verificar ambos estados:

    from crontab import CronTab
    
    cron = CronTab(user="username")
    
    job = cron.new(command='python example1.py', comment="comment")
    job.minute.every(1)
    
    cron.write()
    
    print job.enable()
    print job.enable(False)
    

    El resultado es el siguiente:

    $ python cron4.py
    True
    False
    

    Figura 4

    Comprobaci贸n de validez

    Podemos comprobar f谩cilmente si una tarea es v谩lida o no con el siguiente comando:

    job.is_valid()
    

    El siguiente ejemplo muestra c贸mo utilizar este comando:

    from crontab import CronTab
    
    cron = CronTab(user="username")
    
    job = cron.new(command='python example1.py', comment="comment")
    job.minute.every(1)
    
    cron.write()
    
    print job.is_valid()
    

    Luego de ejecutar el programa anterior, obtenemos la validaci贸n, como se ve en la siguiente figura:

    $ python cron5.py
    True
    

    Figura 5

    Listado de todos los trabajos de Cron

    Todos los trabajos cron, incluidos los trabajos deshabilitados, se pueden enumerar con el siguiente c贸digo:

    for job in cron:
        print job
    

    Agregar esas l铆neas de c贸digo a nuestro primer ejemplo mostrar谩 nuestra tarea imprimiendo en la pantalla lo siguiente:

    $ python cron6.py
    * * * * * python /home/eca/cron/example1.py
    

    Figura 6

    Buscando trabajo

    El m贸dulo crontab de Python tambi茅n nos permite buscar tareas en funci贸n de un criterio de selecci贸n, que puede basarse en un comando, un comentario o una hora programada. Las sintaxis son diferentes para cada caso.

    Encuentra seg煤n el comando:

    cron.find_command("command name")
    

    Aqu铆, ‘nombre de comando’ puede ser una subcoincidencia o una expresi贸n regular.

    Encuentra seg煤n comentario:

    cron.find_comment("comment")
    

    Encuentra seg煤n el tiempo:

    cron.find_time(time schedule)
    

    El siguiente ejemplo muestra c贸mo encontrar una tarea previamente definida, seg煤n los tres criterios mencionados anteriormente:

    from crontab import CronTab
    
    cron = CronTab(user="username")
    
    job = cron.new(command='python example1.py', comment="comment")
    job.minute.every(1)
    
    cron.write()
    
    iter1 = cron.find_command('exam')
    iter2 = cron.find_comment('comment')
    iter3 = cron.find_time("*/1 * * * *")
    
    for item1 in iter1:
        print item1
    
    for item2 in iter2:
        print item2
    
    for item3 in iter3:
        print item3
    

    El resultado es la lista del mismo trabajo tres veces:

    $ python cron7.py
    * * * * * python /home/eca/cron/example1.py # comment
    * * * * * python /home/eca/cron/example1.py # comment
    * * * * * python /home/eca/cron/example1.py # comment
    

    Figura 7

    Como puede ver, encuentra correctamente el comando cron cada vez.

    Eliminar trabajos

    Cada trabajo se puede eliminar por separado. La sintaxis es la siguiente:

    cron.remove(job)
    

    El siguiente c贸digo muestra c贸mo eliminar una tarea que se cre贸 anteriormente. El programa primero crea la tarea. Luego, enumera todas las tareas, mostrando la que acaba de crear. Despu茅s de esto, elimina la tarea y muestra la lista vac铆a resultante.

    from crontab import CronTab
    
    cron = CronTab(user="username")
    
    job = cron.new(command='python example1.py')
    job.minute.every(1)
    
    cron.write()
    print "Job created"
    
    # list all cron jobs (including disabled ones)
    for job in cron:
        print job
    
    cron.remove(job)
    print "Job removed"
    
    # list all cron jobs (including disabled ones)
    for job in cron:
        print job
    

    El resultado es el siguiente:

    $ python cron8.py
    Job created
    * * * * * python /home/eca/cron/example1.py
    Job removed
    

    Figura 8

    Los trabajos tambi茅n se pueden eliminar en funci贸n de una condici贸n. Por ejemplo:

    cron.remove_all(comment="my comment")
    

    Esto eliminar谩 todos los trabajos donde comment="my comment".

    Borrar todos los trabajos

    Todos los trabajos cron se pueden eliminar a la vez mediante el siguiente comando:

    cron.remove_all()
    

    El siguiente ejemplo eliminar谩 todos los trabajos cron y mostrar谩 una lista vac铆a.

    from crontab import CronTab
    
    cron = CronTab(user="username")
    cron.remove_all()
    
    # list all cron jobs (including disabled ones)
    for job in cron:
        print job
    

    Variables ambientales

    Tambi茅n podemos definir variables ambientales espec铆ficas para nuestra tarea programada y mostrarlas en la pantalla. Las variables se guardan en un diccionario. La sintaxis para definir una nueva variable de entorno es la siguiente:

    job.env['VARIABLE_NAME'] = 'Value'
    

    Si queremos obtener los valores de todas las variables ambientales, podemos usar la siguiente sintaxis:

    job.env
    

    El siguiente ejemplo define dos nuevas variables ambientales para la tarea ‘usuario’ y muestra su valor en la pantalla. El c贸digo es el siguiente:

    from crontab import CronTab
    
    cron = CronTab(user="username")
    
    job = cron.new(command='python example1.py')
    job.minute.every(1)
    job.env['MY_ENV1'] = 'A'
    job.env['MY_ENV2'] = 'B'
    
    cron.write()
    
    print job.env
    

    Despu茅s de ejecutar el programa anterior, obtenemos el siguiente resultado:

    $ python cron9.py
    MY_ENV1=A
    MY_ENV2=B
    

    Figura 9

    Adem谩s, las variables de entorno de nivel cron se almacenan en ‘cron.env’.

    Terminando

    El m贸dulo de Python crontab nos proporciona una herramienta 煤til para administrar mediante programaci贸n nuestra aplicaci贸n cron, que est谩 disponible para sistemas similares a Unix. Al usarlo, en lugar de tener que depender de la creaci贸n de crontabs, podemos usar el c贸digo Python para administrar tareas frecuentes.

    El m贸dulo es bastante completo. Aunque ha habido algunas cr铆ticas sobre su comportamiento, contiene funciones para conectarse a cron, crear tareas programadas y administrarlas. Como se muestra en los ejemplos anteriores, su uso es bastante directo. As铆, proporciona una herramienta que permite scripts complejos con la principal caracter铆stica de Python: simplicidad.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *