Programar una tarea repetitiva en Ubuntu Server 20.04 LTS
En Ubuntu, como en la mayoría de las distribuciones GNU/Linux, el servicio que se encarga de ejecutar tareas en intervalos regulares es cron, que está formado por el demonio crond y varias tablas que definen los trabajos que se deben ejecutar y con qué frecuencia.
Normalmente, crond se inicia durante el arranque del sistema y se activa cada minuto para revisar las tablas y comprobar si debe ejecutar alguna acción.
Cada usuario gestiona su propia tabla de trabajos pendientes mediante el comando crontab.
El artículo de hoy lo hemos desarrollado sobre Ubuntu Server pero, para ponerlo en práctica sobre la versión de escritorio, solo tienes que abrir una ventana de terminal. Por ejemplo, usando la combinación de teclas Alt + Control + T.
Crear una tarea programada
Para crear la tabla para un trabajo, ejecutaremos el comando crontab con el argumento -e, que indica que queremos editar:
crontab -e
Para nuestro ejemplo de hoy, vamos a programar el apagado automático del ordenador, todos los días laborales a las 15:30 horas.
Como se trata de una tarea administrativa, deberemos utilizar el comando crontab con privilegios de root, por lo que escribiremos algo como esto:
sudo crontab -e
Como cabe esperar, el sistema nos pide la contraseña de administración. La escribimos y pulsamos la tecla Intro.
Como ocurre con otros comandos, crontab utiliza un editor de textos para que indiquemos nuestras preferencias, por lo que, la primera vez que lo ejecutamos, nos da a elegir entre los editores que haya instalados en estos momentos.
Las próximas veces entrará de forma automática en el editor que hayamos elegido.
Escribimos el número que representa a nuestro editor preferido y pulsamos la tecla Intro. En nuestro caso, mantenemos la opción predeterminada, que es el editor nano.
En cualquier caso, si más adelante queremos cambiar de editor, bastará con modificar el valor de las variables de entorno $EDITOR o $VISUAL. También podemos recurrir al siguiente comando:
sudo update-alternatives --config editor
Como nos ocurrió más arriba, al tratarse de una operación que necesita privilegios administrativos, el sistema nos pide la contraseña. La escribimos y pulsamos la tecla Intro.
Al hacerlo, nos muestra nuevamente el menú donde podemos elegir el editor predeterminado.
Después de esto, en el área de trabajo del editor, aparece automáticamente el contenido del archivo que contendrá las tareas programadas.
En realidad, el contenido inicial del archivo no son más que líneas de comentario para instruirnos sobre el modo de programar tareas. Básicamente, la idea es que cada línea en el archivo de crontab tiene seis datos:
-
Minuto: Un valor entero entre 0 y 59.
-
Hora: Un valor entero entre 0 y 23.
-
Día del mes: Un valor entero entre 1 y 31.
-
Mes del año: Un valor entero entre 1 y 12.
-
Día de la semana: Se puede expresar de dos formas:
-
Como un valor entero entre 0 y 7, donde 0 ó 7 = domingo, 1 = lunes, 2 = martes, etc.
-
Como un texto con los valores sun, mon, tue, wed, thu, fri y sat.
-
-
Orden que será ejecutada por la Shell. crontab no analiza su contenido, sólo envía a la Shell cualquier cosa que haya después del día de la semana y hasta el final de la línea. Si aparece un carácter de porcentaje (%) será interpretado como el final de la línea por lo que, si necesitamos utilizar este carácter en la orden que le enviemos a la Shell, deberemos ponerle justo delante una barra invertida (\%). Lo que haya antes del primer carácter de porcentaje es enviado a la Shell mientras que todo lo que haya después se envía a la entrada estándar.
Los primeros cinco datos pueden expresarse como valores individuales, como rangos de valores (expresados como dos valores separados por un guión), como una lista de valores individuales o rangos (separados por comas) o con un asterisco (*) que representa todos los valores posibles para ese dato.
También podemos indicar un valor de incremento usando el formato /número. Por ejemplo, si quiero que algo se ejecute entre las 5 y las 15 horas, pero sólo las horas impares, puedo escribir en la segunda columna algo como esto: 5-15/2.
Puedes utilizar la página Crontab Made Easy para generar, de forma sencilla, argumentos de programación temporal para crontab.
Como hemos dicho más arriba, para este artículo vamos a suponer que necesitamos programar el apagado automático del ordenador, todos los días laborales a las 15:30 horas. Algo así:
Por lo tanto, nos desplazamos hasta la última línea del archivo y escribimos esto:
30 15 * * 1-5 /sbin/poweroff
En este caso, he decidido utilizar el comando poweroff, pero podría haberme inclinado por halt o incluso por shutdown -h 0.
Aunque,si lo que necesitamos es reiniciar el equipo, debemos decantarnos por reboot.
Al hacerlo, el editor nos preguntará si queremos guardar los cambios que hemos realizado.
A continuación, nos da la oportunidad de cambiar el nombre del archivo, para no perder su valor anterior.
Cuando salimos del editor, el contenido del archivo crontab se analiza para comprobar que no contiene errores. Si todo es correcto, se almacena en /var/spool/cron/crontabs.
Por razones de seguridad, los archivos almacenados dentro de /var/spool/cron/crontabs, solo pueden editarse con el comando crontab.
Valores de tiempo predefinidos
Aunque no son un estándar, la mayoría de las distribuciones de GNU/Linux, entre las que se incluye Ubuntu, admiten una serie de macros para representar valores de tiempo de uso común. son los recogidos en esta tabla:
Como puedes ver, el único que puede necesitar explicación es @reboot. Su funcionamiento se basa en que la tarea asociada se ejecute cada vez que se reinicie el demonio. Como cron no suele reiniciarse, la tarea solo se iniciará cuando se inicie el sistema. De hecho, algunas distribuciones, como las basadas en Debian, refuerzan este comportamiento para que la tarea no vuelva a ejecutarse, incluso si se reiniciara cron.
Otras observaciones
Llegados a este punto, es importante hacer tres observaciones:
-
Se recomienda incluir siempre la ruta completa de los comandos o scripts que incluyamos dentro de una tarea programada. Si no lo hacemos, probablemente el comando se ejecute correctamente, pero dependemos de que su ruta sea encontrada dentro de la variable $PATH y de que ésta haya sido correctamente definida en el momento de ejecutar la tarea programada.
-
La tarea programada se ejecutará con los privilegios de la cuenta en la que se ha creado. Si no hubiésemos utilizado el comando sudo, cuando llegara el momento de ejecutar la tarea, lo haría como si el usuario hubiese escrito la orden en ese preciso momento.
-
Si el ordenador está apagado cuando se cumple un plazo, la tarea no queda aplazada para cuando el equipo esté disponible. En otras palabras, la tarea correspondiente al plazo que se haya perdido no se recuperará.
Muchos comando que están pensados para usarlos con el servicio cron ofrecerán sus resultados generando sucesos con syslog. Puede resultar conveniente el uso de Logcheck para recibir periódicamente vía e-mail los sucesos que ocasionen estos comandos para tener la certeza de que se están ejecutando según lo planeado. Ver el apartado Registro de sucesos en el capítulo 5 de nuestro libro Sistemas Operativos en Red (2ª edición).
Algunos comandos más
Cuando un usuario necesite consultar sus tareas programadas, sólo tendrá que ejecutar el siguiente comando:
crontab -l
Aunque, como habrás imaginado, para las tareas administrativas debemos usar delante el comando sudo:
sudo crontab -l
Para la imagen anterior se han eliminado las líneas de comentario del archivo para hacerlo más legible.
Si lo que necesitas es eliminar tus tareas programadas de una forma sencilla, bastará con ejecutar el siguiente comando:
crontab -r
En el siguiente ejemplo hemos eliminado las tareas programadas y, a continuación, hemos hecho una consulta.
Observa que crontab -r no pide confirmación antes de eliminar las tareas, lo que significa que, al ejecutarlo, se perderán de forma definitiva.
Para evitarlo, puedes recurrir al argumento -i. Esto hará que el comando te pida tu aprobación antes de realizar su tarea. La sintaxis quedará así:
crontab -r -i
… Y esto es todo por el momento. Espero que te resulte útil.