jueves, 2 de diciembre de 2010

Crontab: Programar/Automatizar tareas repetitivas

Imagina que quieres programar una tarea para que se ejecute periódicamente, o en un determinado momento. Por ejemplo, hacer una copia de seguridad de tus archivos el dia 1 de cada mes, o cambiar el fondo de escritorio cada 30 minutos. Para programar tareas en Linux, existe un servicio llamado “cron“.

Servicio cron:

¿Que hace este servicio?
Es un proceso que lee un fichero crontab , donde le indicamos las tareas y cuando queremos realizarlas y el se encarga de ejecutarlas por nosotros en el preciso momento que le hayamos indicado ( pero hay que tener en cuenta que si el pc está apagado en el momento en que la tarea fue programada, entonces esta no será ejecutada por cron, ni siquiera luego una vez que se haya encendido el sistema ya que su tiempo de ejecución expiró.) .

( Existen utilidades gráficas para programar/automatizar tareas, como son Kcron (en KDE) , o Grontab y Gnome-Schedule (en Gnome), con las que puedes hacer lo mismo que se explica en este tema; si las usas con que hagas los primeros tres pasos de "Creación de un crontab para un usuario", y leas la sección "sintaxis de contrab" te será suficiente para aprender a manejarte con ellas ) .

Si queremos definir una nueva tarea para cron podemos ejecutar en la terminal el comando crontab , el cual admite los siguientes parámetros:
$ crontab instala el fichero indicado como fichero crontab del usuario
$ crontab -e para editar este fichero de tareas que lee el servicio “cron”  Al ejecutar este comando se abre el editor nano.
$ crontab -l para mostrar un listado de las tareas actuales del usuario.
$ crontab -r elimina el fichero crontab del usuario ( es decir no usar este comando, ya que si se usa habría que volver a crear el archivo crontab del usuario )

Para impedir que un usuario utilice cron o mejor dicho el comando crontab, basta con agregar su nombre de usuario al archivo /etc/cron.deny .Para permitirle su uso entonces sería agregar su nombre de usuario en /etc/cron.allow, si por alguna razón se desea negar el uso de cron a todos los usuarios, entonces se puede escribir la palabra ALL al inicio de /etc/cron.deny .

-------------------

Creación de un crontab para un usuario:

La opción que nos interesa usar para la creación de tareas principalmente es crontab -e, para ello tenemos primero que crear un archivo crontab para cada usuario ( naturalmente hacemos esto desde cada sesión de un usuario ), y con cada usuario el archivo cron-usuario llevara el nombre del usuario ):
1-Primero creamos con gedit un archivo de texto, con el texto:
SHELL=/bin/bash
DISPLAY=:0
2-Guardamos este archivo con el nombre: cron-usuario , en el directorio /home/usuario
3- En la terminal ejecutamos: crontab cron-usuario ( luego si quieres ya puedes borrar el archivo de texto cron-usuario). Al ejecutar dicho comando se crea un archivo con el nombre del usuario en /var/spool/cron/crontabs/ ; Este archivo no se debe editar directamente, sino a través de la ejecución del comando crontab -e en la terminal.
4- A partir de ahí puedes ejecutar en la terminal: crontab -e , e ir añadiendo las lineas necesarias para que se ejecuten programas, comandos o scripts, como se explica en las secciones siguientes.
5-Al ejecutar la orden crontab -e en la terminal se abre el editor nano: una vez añadida la/s linea/s, que queremos programar como tarea/s, para guardar los cambios se da a la tecla F3, luego a la tecla Intro, y para salir del editor nano, se da a la tecla F2, y luego cerramos la terminal.  Se pueden añadir tantas lineas como se quiera para ejecutar tantas tareas como se deseen.

Con permisos de root se puede editar los crontabs de cualquier otro usuario tecleando: sudo crontab -e -u nombre_del_usuario

Programar/Automatizar una tarea para un  comando:

Si queremos que el comando (por ejemplo: tar cvf backup-firefox.tar /home/usuario/.mozilla , que nos crearía un archivo comprimido como copia de seguridad de toda la configuración del navegador firefox) lo ejecute un usuario, en la terminal ponemos: crontab -e , se abre el editor nano, añadimos el comando y lo guardamos y cerramos nano, como indicamos arriba. La nueva tarea se guardará en el archivo: /var/spool/cron/crontabs/usuario ( para las tareas que quieras que ejecute el usuario ). Este archivo no se debe editar directamente, sino a través de la ejecución del comando crontab -e en la terminal.

Si tienes varios usuarios, para que con cada uno de ellos puedas tener tareas programadas/automatizadas, tienes que realizar los pasos anteriores, ( desde la sesión de usuario correspondiente ) cambiando usuario por el nombre de cada uno de ellos.

Si queremos que el comando se ejecute con permisos de root ( es decir con sudo delante del comando ), en la terminal ponemos: sudo crontab -e , se abre el editor nano, añadimos el comando, y lo guardamos, y cerramos nado como indicamos arriba. La nueva tarea se guardará en el archivo: /var/spool/cron/crontabs/root ( para las tareas que quieras que ejecuten con permisos de root ). Este archivo no se debe editar directamente, sino a través de la ejecución del comando sudo crontab -e en la terminal.

Como puedes ver en /var/spool/cron/crontabs/ habrá tantos archivos con nombres de usuarios, como usuarios que vayan a ejecutar tareas programadas.

Sintaxis de contrab:

Todos estos ficheros de crontab siguen la misma sintaxis. En ellos tenemos una línea por cada tarea o acción a ejecutar y esta línea tiene la siguiente sintaxis:

minutos horas dia-mes mes dia-semana comando

El valor que puede tomar cada campo es como sigue:

- minutos: va de 0 a 59 y representa el minuto en que se ejecuta
- horas: va de 0 a 23 y representa la hora en que se ejecuta
- dia-mes: va de 1 a 31 y es el dia del mes en que se ejecuta
- mes: va de 1 a 12 y representa el mes que se ejecuta
- dia-semana: va de 0 a 7 y el el dia de la semana en que se ejecuta (el domingo se puede indicar con el 0 o con el 7, el lunes es 1, martes 2, etc)
- comando: es el comando a ejecutar (un comando o la ruta a un shell script que queramos ejecutar. )

Con un asterisco * se indica todo es decir todos los minutos, o todos los meses, o todos los dias.
‎También se admiten rangos en los campos:
un guión - significa: 0-15 -> un intervalo de valores: todos los valores de 0 hasta 15
una coma , indica: 15,30,45 -> unos valores determinandos: solo esos tres valores: 15, 30 y 45
una barra / indica: 1-10/2 -> un incremento de valores: valores en incremento de 2 en 2 , empezando desde 1, es decir: 1,3,5,7,9

--------------------------------------------

Esquema de la sintaxis del comando crontab:



-------------------

Ejemplos: ( se omite el comando que se ejecutaría siguiendo las instrucciones dadas por los campos anteriores a él ):

0 1 * * * *    Se ejecuta al minuto 1 de cada hora de todos los días
15 8 * * *    A las 8:15 a.m. de cada día
15 20 * * *    A las 8:15 p.m. de cada día
00 5 * * 0    A las 5 a.m. todos los domingos
* 5 * * 0    Cada minuto de 5:00a.m. a 5:59a.m. todos los domingos
45 19 1 * *    A las 7:45 p.m. del primero de cada mes
01 * 20 7 *    Al minuto 1 de cada hora del 20 de julio
10 1 * 12 1    A la 1:10 a.m. todos los lunes de diciembre
00 12 16 * 3    A las 12h de los días 16 de cada mes y que sea Miércoles
30 9 20 7 4    A las 9:30 a.m. del dia 20 de julio y que sea jueves
30 9 20 7 *    A las 9:30 a.m. del 20 de julio de cualquier día de la semana
20 * * * 6    Al minuto 20 de cada hora de los sábados
20 * * 1 6    Al minuto 20 de cada hora de los sábados de enero
--------------------
--   59 11 * 1-3 1,2,3,4,5    A las 11:59 de lunes a viernes, de enero a marzo
--  45 * 10-25 * 6-7    Al minuto 45 de todas las horas de los días 10 al 25 de todos los meses y que el día sea sábado o domingo
--  10,30,50 * * * 1,3,5    En el minuto 10, 30 y 50 de todas las horas de los días lunes, miércoles y viernes
--  */15 10-14 * * *    Cada quince minutos de las 10:00a.m. a las 2:00p.m.
--  * 12 1-10/2 2,8 *    Todos los minutos de las 12h, en los días 1,3,5,7 y 9 de febrero y agosto. (El incremento en el tercer campo es de 2 y comienza a partir del 1)
--  0 */5 1-10,15,20-23 * 3    Cada 5 horas de los días 1 al 10, el día 15 y del día 20 al 23 de cada mes y que el día sea miércoles
--  3/3 2/4 2 2 2    Cada 3 minutos empezando por el minuto 3 (3,6,9, etc.) de las horas 2,6,10, etc (cada 4 horas empezando en la hora 2) del día 2 de febrero y que sea martes

-------------------

Podemos programar tareas que se ejecuten cada hora, o cierto dia del mes, o todos los meses, o todos los dias, o solo los sábados, o miércoles, etc.
Todo depende de la combinación de valores que pongas en esos campos.
Así que, todas esas tareas periódicas que realizas ocasionalmente (un script para que me limpie de ficheros no necesarios, copias de seguridad, recordatorios, etc) podrían ser programados para ejecutarse de manera automática.

----------------
Programar/Automatizar una tarea para un  script:

En la linea de “comando” del cron ( al ejecutar crontab -e ) no solo puedes poner un comando, también puedes crear un shell script que haga lo que tu quieras y después lo ejecutas como tarea programada con contrab. Podría ser algo como esto:

15,30,45 11-12 1,2,3 * * /home/usuario/Scripts/cambiar_wallpaper.sh ( hay que poner la ruta entera del directorio donde esta guardado el script )   que significa: cada dia 1,2 y 3 de todos los meses, a las 11h y 12h y 15, 30 y 45 minutos ejecuta el script: /home/usuario/scripts/cambia_wallpaper.sh

Como antes, si el script queremos que lo use root debemos ejecutar: sudo crontab -e , y editar el archivo que se abre.

------------------------------

Programar/Automatizar una tarea para un programa gráfico:

Cron ejecuta comandos (en principio) que no impliquen una salida por entorno gráfico, pero después de haber creado el archivo: cron-usuario con el texto que se indica mas arriba ( en la sección "crear un crontab para un usuario" ), y de haber ejecutado en la terminal: crontab cron-usuario , ya podemos editar con contrab -e y añadir la linea correspondiente, poniendo como comando el nombre del archivo ejecutable, por ejemplo:
20 15  * * *  sylpheed  haría que el programa de correo se abriera todos los dias a las 15h 20 minutos.

Editado ( 3-1-2011) : si para ejecutar un programa gráfico solo ponemos su ejecutable la tarea lanzará el programa con su interfaz en inglés, para que se lance el programa con la interfaz en español hay que poner: LANG=es_ES.utf8 ejecutable ; en el ejemplo, si como ejecutable ponemos: firefox, se ejecuta el programa en ingles, si ponemos: LANG=es_ES.utf8 sylpheed , si que se ejecuta el programa en español.

Editado (6-1-2011): Para los que vivan fuera de España escribir en un terminal:  set | grep LANG
Saldrá por ejemplo LANG=es_AR.utf8 para los que vivan en Argentina.
usuario@mint ~ $ set | grep LANG
GDM_LANG=es_AR.utf8
LANG=es_AR.utf8
usuario@mint ~ $

En el ejemplo habría que poner, si vives en Argentina,  LANG=es_AR.utf8 sylpheed  .El idioma que aparece al ejecutar el comando varia en función de la lenguna ( o la variante del Español ) en la que iniciemos el sistema.

Como antes, si el programa gráfico queremos que lo use root debemos ejecutar: sudo crontab -e y editar el archivo que se abre.

-------------------------------

Un ejemplo, a modo de chuleta o recordatorio,  de como seria el texto que aparece al ejecutar contrab -e y que permitiría ejecutar tanto un script, como un programa gráfico o un comando sería:

SHELL=/bin/bash
DISPLAY=:0

# sintaxis: minutos horas dia-mes mes dia-semana comando
# guión - = intervalo de valores
# coma , = valores determinados
# barra / = incremento de valores
# asterisco * = todo
# ejemplo para ejecutar un script
20 17 * * * /home/usuario/Scripts/cambiar_wallpaper.sh
# ejemplo para ejecutar un programa gráfico
20 15 * * * LANG=es_ES.utf8 sylpheed
# ejemplo para ejecutar un comando
32 17 * * * tar cvf backup-firefox.tar /home/usuario/.mozilla

-------------------------------

Este tema lo he podido escribir gracias a la inestimable y desinteresada ayuda tanto de Miguel k3b - usuario de http://foro-ubuntu-guia.blogspot.com/ , como de Sanatas -usuario de Guadalinex  http://www.guadalinex.org/participa/foros/foro/25 - ( puestos por su orden alfabético ), a los que desde aquí agradezco su amabilidad y paciencia conmigo.

----------------------------------------------------------------------------

10 comentarios:

  1. Excelente guía me la guardo la necesitare pronto cuando aprenda bien hacer scripts

    ResponderEliminar
  2. Hola tengo una duda para hacer las tareas a traves del panel de control de plesk. Como seria la instrucción o comando para poner?

    Por ejemplo yo tengo esto que seria la ruta del archivo pero creo que delante del /var debe de llevar algo, me podrias indicar?
    /var/www/vhosts/dominio.com/httpdocs/admin/admin_cron_newuser.php

    ResponderEliminar
  3. Pablo:
    No uso el control de plesck (http://www.galeonpro.com/ayuda/panel-de-control-plesk/Pn272/) . Pero he encontrado un manual en .pdf: http://download1.parallels.com/Plesk/PPP9/Doc/es-ES/plesk-9.0-clients-guide-es-es.pdf Espero que te ayude.

    ResponderEliminar
  4. Muchas gracias Hatteras, lo probare a ver, de todos modos estos dias estoy recibiendo unos emails cuando se ejecutan esas tareas, me indica la direccion del archivo y al final me dice permissed denegaded, esto es quizás que esos archivos deben de tener chmod 666?

    ResponderEliminar
  5. Pablo:
    permisos 666: permisos de lectura y escritura para todos ( para el propietario, el grupo, y los demás )
    http://hatteras.wordpress.com/2008/12/05/permisos-de-archivos-o-directorios/

    ResponderEliminar
  6. Muy bien perfecto, me sirvió demasiado, excelente manual, muy completo

    ResponderEliminar
  7. Excelente, recordando y ahora implementando con shell

    ResponderEliminar
  8. Hola hatteras, tengo una pequeña duda, he colocado un script para que se ejecute diariamente dentro de /etc/cron.daily, he mirado dentro de /etc/crontab para saber a que hora se ejecuta las tareas alojadas en /etc/cron.daily y me sale lo siguiente:

    25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

    Según dice el script que esta alojado en /etc/cron.daily se ejecutaría a las 6.25, mi duda es si el sistema esta apagado no se ejecuta o se ejecuta más tarde ....

    Saludos...

    ResponderEliminar
  9. Gracias. Gnome-schelude sólo me ejecutaba las tareas cuando no cerraba su ventana. Asi desde la terminal, con crontab funcionan perfectamente las tareas programadas. Saludos.

    ResponderEliminar

A la vez que haces un comentario, por favor da una puntuación al tema: malo, normal, bueno o muy bueno.
Gracias.