Automatizando tareas
Cron es un programa o demonio (daemon) que permite ejecutar otros programas o scripts en un lapso de tiempo y una periodicidad especificada por el usuario. Su comportamiento esta regulado por su archivo de configuración, que se llama crontab. Cada usuario del sistema posee un archivo crontab personalizado y sólo el usuario root puede modificar el archivo crontab de otro usuario. Si se desea agregar un archivo crontab, es necesario entrar (”logearse”) primero como ese usuario.
Cómo editar el archivo crontab
Un usuario s?o puede hacer uso de crontab si su nombre aparece en: /etc/cron.allow
Si este archivo no existe, el usuario puede usar crontab a menos que su nombre aparezca en:
/etc/cron.deny.
La sintaxis del archivo crontab es muy clara y r?ida. Hay seis campos por cada linea, y cada campo est?separado por un espacio. Los primeros cinco campos espec?ican el momento preciso de ejecuci?, mientras que el sexto campo es el propio comando o script que se ejecutar? Los primeros cinco campos son:
# m h dom mon dow /commando/a/ejecutar<br /> - - - - - -<br /> | | | | | |<br /> | | | | | +----- d? de la semana (0 - 6) (dom = 0)<br /> | | | | +------- mes (1 - 12)<br /> | | | +--------- d? del mes (1 - 31)<br /> | | +----------- hora (0 - 23)<br /> | +------------- minuto (0 - 59)<br /> +---------------- espacio vac? (no poner nada)</pre><br /><img src="../wp-content/uploads/2009/05/chuleta-cron.png" border="0" alt="" width="800" height="395" align="bottom" /><br />Para editar el archivo crontab s?o es necesario abrir una consola de comandos y ejecutar el comando:<br /><pre style="margin-bottom: 0.5cm;">crontab -e</pre><br />SHELL=/bin/bash<br />PATH=/sbin:/bin:/usr/sbin:/usr/bin<br />MAILTO=root<br />HOME=/<br /><br /># run-parts<br />01 * * * * root nice -n 19 run-parts /etc/cron.hourly<br />50 0 * * * root nice -n 19 run-parts /etc/cron.daily<br />22 4 * * 0 root nice -n 19 run-parts /etc/cron.weekly<br />42 4 1 * * root nice -n 19 run-parts /etc/cron.monthly<br /><br />Para agregar, quitar o modificar tareas, hay que editar el crontab. Esto se hace con la orden crontab -e, que abrir?el editor definido en la variable de entorno EDITOR y cargar?el archivo crontab correspondiente al usuario que est?logueado.<br /><br />Cada vez que se ejecuta el crontab, se env? un mail al usuario que aparece en la variable de entorno MAILTO, si est?habilitado, indic?dole la tarea realizada.<br /><br /><strong>La sintaxis en s?</strong><br /><br />El s?bolo Numeral "#" es un comentario, todo lo que se encuentre despu? de ese car?ter no ser?ejecutado por cron. El momento de ejecuci? se especifica de acuerdo con la siguiente tabla:<br /><ul><br /> <li><br /><p style="margin-bottom: 0cm;">Minutos: (0-59)</p><br /></li><br /> <li><br /><p style="margin-bottom: 0cm;">Horas: (0-23)</p><br /></li><br /> <li><br /><p style="margin-bottom: 0cm;">D?s: (1-31)</p><br /></li><br /> <li><br /><p style="margin-bottom: 0cm;">Mes: (1-12)</p><br /></li><br /> <li>D? de la semana: (0-6), siendo 1=Lunes, 2=Martes, ? 6=s?ado y 0=Domingo</li><br /></ul><br />Para especificar todos los valores posibles de una variable se utiliza un asterisco (*).<br />La ?tima columna corresponde al path absoluto del binario o script que se quiere ejecutar.<br /><br /><strong>Por ejemplo:</strong><br /><br />24 12 * * 1 /usr/bin/who >> /home/hola.txt<br />Ejecuta la orden who todos los lunes a las 12:24 y guarda la salida en el archivo hola.txt<br /><br />Para especificar dos o m? valores en cada variable, estas deben estar separadas por comas, siguiendo con el ejemplo anterior:<br /><br />0,24 * * * 1 /usr/bin/who >> /home/hola.txt<br /><br />Ejecuta la orden who todos los lunes cada media hora y guarda la salida en el archivo hola.txt<br /><br />Si queremos que se ejecute cada 15 minutos ser?:<br /><br />0,15,30,45 * * * * /usr/bin/who >> /home/quien.tex<br />?br />*/15 * * * * /usr/bin/who >> /home/quien.tex<br />En este ejemplo veremos como pasarle mas de un comando al cron y de paso como puede programarse una descarga:<br /><br />30 21 * * * cd /media/sda7/dexter/distributions/isos;wget <a href="http://hola.com/archivo_a_descargar.loquesea">http://hola.com/archivo_a_descargar.loquesea</a><br /><br />Este otro es para programar el apagado de la PC. En este caso todos los s?ados a las 9:30 pm.<br /><br />30 21 * * 6 /sbin/shutdown -h now<br />Si es la primera vez que lo ejecutamos, veremos un archivo vac? en el editor <a href="http://doc.ubuntu-es.org/Nano">nano</a> (editor de textos en consola de Gnome en Ubuntu). En este caso, si agregamos la siguiente l?ea al archivo:<br /><pre style="margin-bottom: 0.5cm;">45 19 * * * rm /home/NombreDeUsuario/tmp/*</pre><br />estaremos indicando a <strong>cron</strong> que el contenido del directorio <em>/home/NombreDeUsuario/tmp/</em> ser?borrado todos los d?s a las 7:45 PM. Si queremos conservar esta instrucci?, tendremos que guardar el archivo pulsando la tecla <strong>F3</strong>, y salir de <a href="http://doc.ubuntu-es.org/Nano">nano</a> pulsando la tecla <strong>F2</strong>. Veremos el mensaje:<br /><pre style="margin-bottom: 0.5cm;">crontab:installing new crontab</pre><br />que indica que una nueva tarea ha sido agregada a cron. Si ejecutamos el comando:<br /><pre style="margin-bottom: 0.5cm;">crontab -l</pre><br />empleando la <strong>opci? -l</strong>, veremos las tareas estipuladas en crontab. En este caso s?o ver?mos la tarea que acabamos de agregar, pero si nuestro crontab ya ten? tareas programadas tambi? aparecer?n.<br /><table border="0" cellspacing="0" cellpadding="2" width="883" bgcolor="#d9e7ed"><col width="44"></col> <col width="831"></col><br /><tbody><br /><tr><br /><td width="44"><a href="http://doc.ubuntu-es.org/Imagen:Important.png"><span style="color: #000080;"><img src="http://doc.ubuntu-es.org/images/f/ff/Important.png" border="1" alt="Imagen:Important.png" width="38" height="38" align="bottom" /></span></a></td><br /><td width="831">Es un fallo com? el empezar a poner alg? dato debajo de "#", por lo que el archivo acaba estando mal codificado y nos aparece el error:<br /><pre>crontab: installing new crontab<br />"/tmp/crontab.bm5Oqc/crontab":1: bad command<br />errors in crontab file, can't install.<br />Do you want to retry the same edit?</pre><br />En caso de que esto nos ocurra, podemos pulsar la "y" de "yes" para corregir la estructura de nuestro crontab. Seguramente hayamos puesto un dato temporal de m? (un asterisco muy probablemente). Debemos asegurarnos que en cada l?ea tenemos 5 cifras para determinar la periodicidad y luego el comando (* * * * * comando).</td><br /></tr><br /></tbody></table><br />La <strong>opci? -r</strong> elimina el archivo crontab del usuario, o lo que es lo mismo, <em>todas la tareas programadas en nuestro crontab</em>, as?que no se usa muy a menudo, y cuando se usa ha de emplearse con mucha precauci?.<br /><table border="0" cellspacing="0" cellpadding="2" width="883" bgcolor="#ebdab5"><col width="53"></col> <col width="822"></col><br /><tbody><br /><tr><br /><td width="53"><a href="http://doc.ubuntu-es.org/Imagen:Clip.png"><span style="color: #000080;"><img src="http://doc.ubuntu-es.org/images/e/e6/Clip.png" border="1" alt="Imagen:Clip.png" width="45" height="46" align="bottom" /></span></a></td><br /><td width="822">Si queremos usar otro editor de consola que no sea <strong>nano</strong> (como por ejemplo, <strong>vim</strong>, es necesario exportar la variable de ambiente EDITOR. Para ello, podemos escribir en consola de comandos y escribir:<br /><pre style="margin-bottom: 0.5cm;">export EDITOR="vim"</pre><br />Si deseamos cambiar de editor de manera permamente, tendremos que agregar esta misma l?ea al archivo:<br /><pre>$HOME/.bashrc.</pre><br /></td><br /></tr><br /></tbody></table><br />Habitualmente, <strong>cron</strong> env? un e-mail de notificaci? al usuario propietario de crontab. Esto puede llegar a ser molesto, sobre todo si tenemos un cron que se ejecuta con mucha frecuencia. Para deshabilitar el envio de este e-mail agregaremos lo siguiente al final de cada l?ea del crontab:<br /><pre style="margin-bottom: 0.5cm;">>/dev/null 2>&1</pre><br /><h2>Ejecutar aplicaciones gr?icas con <em>cron</em></h2><br /><strong>Cron</strong> ejecuta comandos (en principio) que no impliquen una salida por entorno gr?ico, con lo que en principio, si queremos que nos abra una terminal de gnome o el gestor de correo <a href="http://doc.ubuntu-es.org/Thunderbird">Mozilla Thunderbird</a>, no podemos editar <em>crontab</em> de la siguiente manera:<br /><pre style="margin-bottom: 0.5cm;">0 8 * * * thunderbird</pre><br />Esta l?ea en principio abrir? el programa cada d? a las 8 a.m., pero escrito de esta forma <strong>cron</strong> no puede interactuar con el entorno gr?ico y la orden no se ejecuta. Para solventarlo, debemos a?dir el siguiente elemento antes del comando que queramos que se ejecute:<br /><pre style="margin-bottom: 0.5cm;">DISPLAY=":0"</pre><br />de modo que la l?ea nos quede as?<br /><pre>0 8 * * * <strong>DISPLAY=":0"</strong> thunderbird<br /> />
Editores gráficos de crontab
Podemos editar gráficamente y de forma muy sencilla el archivo crontab mediante aplicaciones gráficas como:
-
- gnome-schedule (recomendado): Es el editor gráfico de crontab estéticamente más depurado, además e estar completamente traducido al español. Además, nos “traduce” los comandos a u lenguaje más entendible, por lo que requiere menos “soltura” con la edición de crontab.
-
- gcrontab: Editor gráfico de crontab muy funcional, pero estéticamente no tan depurado.
-
- kcron: Editor gráfico de crontab que es un componente integrado en el módulo de administración de KDE.
Estas aplicaciones abren automáticamente nuestro archivo crontab en caso de tener uno ya creado.
Algunos ejemplos
Algunos ejemplos de líneas que podemos añadir a crontab son:
-
- Para el comando ping al equipo 192.168.0.1 cada minuto, de cada hora, de cada día, de cada mes. Es decir, hacer un ping a cada minuto (nótese la terminación en >/dev/null 2>&1 para no recibir la notificación).
- * * * * * /sbin/ping -c 1 192.168.0.1 >> /dev/null
-
- Para ejecutar lo mismo, pero que el ping sólo se ejecute los días laborables de la semana (de Lunes a Viernes) a las 8:00 PM en punto y sólo durante el mes de octubre.
- 0 20 * 10 1-5 /sbin/ping -c 1 192.168.0.1 >> /dev/null
-
- Para ejecutar un script de respaldo en python de lunes a domingo a medianoche (0:00 AM) los días 1, 15 y 28 de cada mes (para asegurarnos que en febrero también se haga)
- 0 0 1,15,28 * * /home/mmonrdz/scripts/respaldar.py
-
- Para ejecutar un script que actualiza la base de datos de cotizaciones todos los lunes a las 7:00 AM, 7:50 AM, 8:00 AM y 8:50 AM sin enviar el e-mail de notificación.
- 0,50 7,8 * * 1 /home/mmonrdz/scripts/dbcotiza.pl >/dev/null 2>&1
-
- Para abrir un terminal de Gnome (consola de comandos) y ejecutar en ella rtorrent cada día a la 1 a.m.:
- 0 1 * * * DISPLAY=”:0″ gnome-terminal –command=rtorrent
Ver también
Fuentes
- Artículo Editando el Crontab en el espacio Despabilando la Mononeurona
Ejemplo de cron: BACKUP de datos
El objetivo es montar dos tipos de copias, por una parte haremos backups de ficheros y directorios, esto nos permitirá poder restaurar archivos o directorios de manera individual. El otro tipo de copia nos permitirá recuperar nuestro sistema en caso de urgencia.
Backup de directorios y ficheros
Se trata de hacer un backup de todos los archivos de nuestro usuario. A demás, mantendremos un histórico de backups, haremos una copia diaria (lunes, martes, miércoles, etc .), cada lunes machacaremos la copia del lunes anterior y así con todos los días.
El procedimiento es sencillo, elegiremos los directorios y ficheros de los que queremos hacer el backup, y los copiaremos.
cp -rp ~/banyut /media/sdb5/backup/domingo
Es totalmente funcional, pero la verdad es que no es eficiente, el problema está en que cada lunes nos hará una copia completa de todos los archivos que tenemos en el directorio, cuando lo que seria deseable es que solo copiara los modificados o los creados des del último backup.
No hay problema, tenemos otra instrucción que nos ofrece esta funcionalidad.
rsync -altgvbp /home/banyut /media/sdb5/backup/domingo
Hoy no explicaré el comando rsync ni sus opciones, si alguien tiene alguna duda primero que consulte “man rsync” y después que pregunte.
Bueno, ya tenemos la instrucción que nos permite poder realizar nuestra copia. El siguiente paso es que estas se realicen de manera automática, para ello utilizaremos otra instrucción que nos ofrece el sistema crontab.
Crontab nos permite ejecutar aplicaciones en un momento determinado, una única vez o de manera recurrente. En un principio puede parecer algo liosa pero en realidad es muy fácil de usar.
crontab -e
Esta instrucción nos permite editar el archivo /etc/crontab, en el que programaremos las instrucciones que queremos ejecutar.
Cada linea de este archivo esta formada por 7 columnas
- Minutos (de 0 a 59)
-
Horas (de 0 a 23)
-
Dia (de 1 a 31)
-
Mes (de 1 a 12)
-
Dia de la semana (de 0 a 7, donde 0 o 7 es domingo)
-
usuario (opcional)
-
orden a ejecutar
Un asterisco en cualquiera de las primeras 5 columnas indica todos, es decir si queremos que algo se ejecute todos los meses en la columna del mes podremos un asterisco.
En realidad es un poco mas complejo pero por el momento ya nos vale así.
Como funcionan estas columnas.
5 * * * * se ejecutara el minuto 5 de cada hora todos los días.
0 2 * * * a las 2:00H en punto cada día.
0 2 * * 0 a las 2:00h todos los domingos del año.
* 5 * * 1 todos los minutos de las 5:00 a 5:59 de todos los lunes.
2 * 10 4 * el minuto dos de cada hora el dia 10 de abril de cada año.
0 3 * * 6 a las 03:00 horas de todos los sábados
En cada una de estas columnas podemos poner más de un valor, o incluso un rango, esto se hace separando cada valor mediante una coma o un rango mediante un guión.
Así en la columna día de la semana podemos poner 1,3,5 que indicara que se ejecute los lunes, miércoles y viernes. O en la columna mes para indicar la primera quincena podemos poner 1-15.
Esto aún podemos complicarlo un pelín más, tenemos otra operación el símbolo “/”, que indica un incremento, por ejemplo, si en la columna minutos ponemos */15 se ejecutará cada 15 minutos, o si en la columna dias ponemos 1-10/2, se ejecutará los dias 1,3,5,7 y 9.
Por último un ejemplo más complejo.
0 */2 1-15,23,28-31 * 0,6
Se ejecutara cada dos horas los días 1 al 15,el 23, 28, 29, 30 y 31 de todos los meses pero solo cuando sean sábado o domingo.
Ala, como se os ha quedado el cuerpo!!!!
Sabiendo esto, ahora podremos conseguir que nuestros backups se ejecuten de manera automática.
Después de teclear crontab -e añadiremos las siguientes lineas.
0 1 * * 0 instrucción_lunes
0 1 * * 1 instrucción_martes
0 1 * * 2 instrucción_miercoles
0 1 * * 3 instrucción_jueves
0 1 * * 4 instrucción_viernes
0 1 * * 5 instrucción_sabado
0 1 * * 6 instrucción_domingo
Con esto conseguiremos que se ejecute cada día a las 01:00 horas las instrucciones indicadas. Podemos substituir “instrucción_******” por la orden rsync arriba descrita.
De todas formas lo haremos un pelín más completo, crearemos un script para cada día de la semana, además recogeremos un log.
Empezaremos creando los directorios necesarios.
mkdir ~/.crono_bak
cd ~/.crono_bak
Dentro del directorio que acabamos de crear, crearemos siete ficheros mas llamados lunes.sh, martes.sh, …, domingo.sh y en su interior pondremos lo siguiente.
#!/bin/bash
pathLog=”/media/sdb5/backup/logLunes.log“
echo ———————————————————————– >> $pathLog
echo —INICI COPIA SEGURETAT LUNES >> $pathLog
date >> $pathLog
echo ———————————————————————– >> $pathLog
echo — Iniciem Sincronització directori /home/monti >> $pathLog
rsync -altgvb /home/monti /media/sdb5/backup/sistema/lunes >> $pathLog
echo ———————————————————————– >> $pathLog
echo — Sincronització Finalitzada >> $pathLog
date >> $pathLog
echo ———————————————————————– >> $pathLog
Este código es el que corresponde al script del lunes, para los otros seis haremos lo mismo pero substituyendo Lunes por el día de la semana concreto.
El script ejecuta la instrucción rsync, el resto de las lineas lo que hacen es generar un fichero log.
Una vez creados los siete ficheros, tendremos que darles permiso para poder ejecutarlos.
chmod +x *.sh
Para que se ejecute todos los dias a la 1 de la mañana, nuestro crontab quedará así.
# m h dom mon dow command
0 1 * * 1 /home/banyut/.crono_back/lunes.sh >>/media/sdb5/backup/logcrono.log
0 1 * * 2 /home/banyut/.crono_back/martes.sh >>/media/sdb5/backup/logcrono.log
0 1 * * 3 /home/banyut/.crono_back/miercoles.sh >>/media/sdb5/backup/logcrono.log
0 1 * * 4 /home/banyut/.crono_back/jueves.sh >>/media/sdb5/backup/logcrono.log
0 1 * * 5 /home/banyut/.crono_back/viernes.sh >>/media/sdb5/backup/logcrono.log
0 1 * * 6 /home/banyut/.crono_back/sabado.sh >>/media/sdb5/backup/logcrono.log
0 1 * * 0 /home/banyut/.crono_back/domingo.sh >>/media/sdb5/backup/logcrono.log
Por su puesto, la ruta /media/sdb5/backup/sistema/ tiene que existir y en su interior tiene que haber 7 directorios llamados lunes, martes, etc.
bueno, ya se que el script es muy mejorable y que se podria haber hecho con un solo fichero en vez que con siete, pero creo que para empezar ya esta bien así.
Para poder revisar nuestra programación ejecutaremos:
crontab -l
He dado por hecho que el demonio cron esta activado, para comprobar esto podemos ejecutar.
ps -ef | grep crontab
En caso que no este en marcha lo iniciaremos de la siguiente forma
sudo /etc/init.d/cron start
Por último para ver si se ha ejecutado bien podemos mirar el log que hemos creado en /media/sdb5/backup/logcrono.log podemos mirar los logs del dia en concreto dentro de la carpeta /media/sdb5/backup/*****.log,tambien podemos ver cuando se ha ejecutado nuestro crontab consultando el log del systema.
cat /var/log/syslog |grep crontab
