Guía rápida sobre cron

Cron es una herramienta que te permite ejecutar comandos de forma programada. Mientras el agente de cron esté corriendo, podrás especificar cosas como pedir que un script o comando se ejecute periódicamente, cada 15 minutos, cada minuto, cada hora, cada noche, cada domingo, cada sábado a las 14:37 horas, cada día 5 de mes a las 02:51 horas… En fin, que podrás hacerlo de forma muy flexible.

Para poder modificar las tareas programadas, puedes modificar el crontab, que es la tabla de tareas periódicas. En esta guía te quiero contar cómo modificar esta tabla y el formato de lo que debes poner en el archivo.

Introducción al crontab

Para cambiar la configuración de tu agenda puedes usar el comando crontab -e desde la línea de comandos. Si ejecutas este comando, se abrirá el editor de textos por defecto que tengas configurado en tu sistema, con un archivo que puede que esté vacío o que ya contenga cosas.

Dentro de este archivo, puedes meter tres tipos de línea:

  • Líneas en blanco.
  • Líneas que comienzan con un #. Se denominan comentarios, y si no sabes de programación, te vienen bien para anotar cosas. El ordenador las va a ignorar, así que ahí es donde puedes dejar explicaciones o cualquier otro dato que quieras conservar para que puedas volver a leerlo más tarde con calma.
  • Líneas que contienen una tarea programada que quieres que cron ejecute.

Vamos a lo gordo porque realmente el formato puede resultar un poco confuso. Cada línea contiene un comando a ejecutar y el calendario que quieres que tenga.

Calendarios

El calendario especifica cuándo quieres que se repita la tarea. Por ejemplo, los jueves a las 15:30 o cada día 1 a las 02:00 AM. Para especificar el calendario, tienes que poner cinco números separados por espacios al principio de la línea. Estos cinco números siguen el siguiente formato:

minuto   hora   dia-del-mes   mes   dia-de-la-semana

Los rangos de los números son los esperables. Como minuto puedes poner un número comprendido entre 0 y 59; como hora uno entre 0 y 23. El día del mes se comprende entre 1 y 31, sabiendo que hay meses con menos días. El mes también está entre 1 y 12. Ahora bien, para el día de la semana, puedes usar un número de 1 a 7, donde 1 es lunes, 2 es martes… y así hasta 7, que es domingo; o bien puedes especificar también un 0 para el domingo, usando por lo tanto un número entre 0 y 6. Tal vez si administras sistemas esto te suene porque muchos sistemas usan esta notación igualmente, dejando el 0 para el domingo y el 6 para sábado.

Además de un número, puedes poner un asterisco (*) cuando quieras indicar que te da lo mismo lo que valga el campo. Por ejemplo, si quieres ejecutar una tarea todos los días, podrías usar asteriscos para los campos dia-del-mes, mes y dia-de-la-semana, para indicar que lo único que te importa es la hora, pero la fecha vale cualquiera. Por ejemplo, aquí van algunos calendarios:

  • 30 18 * * *: ejecutaría una tarea todos los días a las 18:30. (Me da igual el día del mes, o el mes, o el día de la semana).
  • 0 2 1 * *: ejecutará una tarea cada día 1 a las 2 de la mañana. (Sea el mes que sea).
  • 0 6 * * 1: ejecutará una tarea cada lunes a las 6 de la mañana, sea el día que sea.

Otra cosa que puedes hacer es pedirle que se ejecute cada N minutos, o cada N horas, o cada N días. Para ello le pones un asterisco (*), seguido de una barra y de cada cuánto tiempo quieres que se repita. Por ejemplo, si quieres ejecutar una tarea cada 5 minutos, puedes usar */5 * * * *, que la ejecuta sea el día que sea o la hora que sea, cada 5 minutos.

Por último, también voy a indicarte que puedes usar directamente números separados por comas para tener una mayor precisión. Así que si quieres ejecutar una tarea a las 8 de la mañana el día 1 de enero, abril, julio y octubre puedes usar la secuencia 0 8 1 1,4,7,10 *.

Establecer un calendario es una tarea que puede resultar a veces complicada de depurar, así que te voy a mencionar este enlace para que puedas simular un calendario y traducir la explicación a humano: https://crontab.run/es.

Comandos

Finalmente, luego del calendario vendría el comando que quieras que se ejecute. Aquí, ten en cuenta que es bastante probable que se ignoren las variables de entorno que hayas podido declarar en tu terminal, así como otros directorios que hayas metido al PATH, que generalmente y salvo que lo reconfigures, sólo contendrá /usr/bin y /bin. Por lo tanto, mi consejo es que en cualquier caso uses rutas absolutas para cualquier comando que vayas a ejecutar y así evitar problemas.

Por ejemplo, la siguiente regla de cron ejecutaría el script /home/danirod/scripts/send_analytics.sh cada mañana a las 7:00:

0 7 * * * /home/danirod/scripts/send_analytics.sh > /home/danirod/scripts/log

Observa que puedo poner caracteres como > o 2> para enviar la salida del comando que esté ejecutando a un archivo. Esto es aceptado y es una forma excelente de poder luego ver qué ha pasado, sobre todo en caso de error, así que no pierdas de vista la ocasión de ponerlo y guardar el log en alguna parte para poder detectar errores si compruebas que las tareas programadas no se están ejecutando bien. Solo recuerda, de nuevo, que debes usar rutas absolutas, porque si no el archivo se podría guardar en ubicaciones inesperadas.

Permisos

Como consideraciones finales, ten en cuenta que cada usuario del sistema tiene su propio crontab, para especificar su propia agenda. Los comandos se lanzan siempre bajo el usuario al que le pertenece el crontab.

Eso significa que si ejecutas crontab -e con tu perfil, los comandos correrán en tu nombre y por lo tanto tendrán los permisos que tenga tu cuenta. La cuenta root tiene su propio crontab, que puedes modificar como sudo crontab -e (o cambiando antes a root si no tienes sudo), con el que podrás hacer cualquier cosa, aunque mi consejo es que no lo emplees salvo que necesites hacer tareas restringidas (por ejemplo, reiniciar el servidor web cada noche a golpe de comando de systemctl).

FreeBSD 13.2-RELEASE ya está disponible

FreeBSD 13.2 es la actualización de la versión 13 de FreeBSD para este cuatrimestre. Actualiza paquetes e incorpora nuevas funciones y mejoras de rendimiento y estabilidad en el resto del sistema operativo.

La última versión de FreeBSD, uno de los sistemas operativos de tipo BSD de código abierto más importantes del mercado, ya está disponible. Se trata de la versión 13.2, que continúa el linaje de FreeBSD 13 incorporando correcciones de errores y nuevas funciones. Muchos paquetes de software disponibles de serie en FreeBSD o en sus repositorios principales han sido actualizados. OpenSSH ahora usa la versión 9.2p1 y OpenSSL la 1.1.1t. También se ha actualizado la suite de compiladores de LLVM a la versión 14.0.5.

Entre los cambios más relevantes, vuelve a estar disponible el driver para WireGuard a nivel de kernel, el cual se tuvo que retirar anteriormente debido a los problemas que tenía cuando se introdujo por primera vez. Ahora también, el soporte para ASLR estará activo por defecto al ejecutar programas de 64 bits. ASLR es una técnica de seguridad informática que carga los programas en posiciones aleatorias, en vez de usar siempre exactamente la misma disposición de memoria virtual, lo que es más seguro porque en caso de comprometer el sistema, un proceso malicioso ya no puede asumir tan fácilmente en qué partes de la memoria están los datos de un programa en ejecución.

La compatibilidad con Linux ha mejorado (para nuevos: FreeBSD no es Linux). Especialmente en ARM64, donde ahora la ABI para ejecutar procesos de Linux está al mismo nivel que la de la arquitectura AMD64, incluyendo el nuevo soporte para ptrace. En esta versión de FreeBSD, se ha añadido la herramienta nproc, que funciona exactamente igual que la que usa GNU Coreutils en cualquier distro GNU/Linux, para facilitar la creación de scripts portables. También será posible decodificar llamadas a sistema en procesos de Linux desde kdump.

passwd: todo lo que debes saber

Un tutorial para poder utilizar el comando passwd que puede ayudar a las personas que recién llegan a UNIX.

El post en el que explicaba cómo recuperar la contraseña de Debian me dio la idea de profundizar más en el funcionamiento del comando passwd, ya que tiene varias formas de operar según cómo se llame a este comando.

passwd sirve para cambiar la contraseña de una cuenta. Si ejecutas el comando normal en tu terminal, por ejemplo, passwd, bajo tu propia cuenta de usuario solo podrás cambiar tu propia contraseña. Sin embargo, el auténtico poder de este comando está en invocarlo como superusuario (es decir, como root). Cuando la cuenta root ejecuta este comando, puede cambiar cualquier contraseña: la suya o la de otra cuenta.

Cuando invoques passwd con una cuenta normal, lo primero que hará es pedirte la contraseña actual, y así lo veremos cuando dice Current password. Aquí tenemos que meter la contraseña que tenemos ahora mismo. Esto es una medida de precaución para asegurarse de que un script automatizado no trata de cambiar nuestra contraseña sin permiso.

Ten en cuenta que cuando escribas una contraseña, no la verás por pantalla. Igual que pasa con el comando sudo, no habrá feedback. Ni si quiera unos asteriscos. Cuando empieces a escribir la contraseña, hazlo con determinación y no te detengas a medio de teclearla, para no cometer errores.

Después de escribir la contraseña actual y pulsar Enter, el sistema nos preguntará por la contraseña nueva que queramos establecer. En total la tendremos que escribir dos veces, porque nos pedirá confirmación. Así, si la hemos escrito mal, nos avisará para no bloquear nuestro sistema.

$ passwd
Current password:
New password:
Retype new password:
passwd: password updated successfully

Sobre esto, varias notas extra:

  • La configuración del sistema operativo podría traer reglas adicionales que pueden impedir que se guarde la contraseña. Por ejemplo, es posible que rechace cambiar la contraseña si no tiene un número mínimo de caracteres, o incluso si no junta alguna mayúscula o dígito.
  • Es posible que si pones la misma contraseña como nueva contraseña, te lo rechace y te diga que es la misma contraseña de todos modos.

Por último, el auténtico poder de este comando está en lanzarlo como root. Si lo hacemos podremos cambiar la contraseña de cualquier usuario si lo especificamos como parámetro al lanzar el comando. En este caso, de hecho, passwd no preguntará por la contraseña, lo que le convierte también en el comando ideal para usar si tenemos que recuperar una contraseña en concreto:

# passwd ana
New password:
Retype new password:
passwd: password updated successfully

Diccionario UNIX: Tarball

Puede que alguna vez hayas escuchado el término tarball. En esta entrada de blog te quiero contar qué es un tarball. Más concretamente, qué tipos de tarball hay.

Un tarball es simplemente el apodo que recibe un archivo TAR. El origen de la palabra tarball simplemente viene de un juego de palabras, debido a que en inglés, «tar» también quiere decir «alquitrán». Al final del día, no es más que una forma cariñosa de referirse a uno de estos archivos. Pero, ¿qué es realmente un archivo TAR?

TAR es un archivador. Es un formato diseñado para tomar varios archivos y juntarlos en uno único. Por ejemplo, puedes tomar todos los logs de la carpeta /var/log, que estarán dispersos con múltiples nombres, y fabricar un único archivo tar (un tarball) con el que será más fácil de archivar o compartir los datos.

Esquema de cómo funciona (más o menos) un archivo TAR.

El origen de TAR viene de Tape Archiver, y es que TAR es un formato y un programa que lleva con nosotros muchos años. Precisamente el objetivo inicial de TAR era juntar varios archivos en un mismo flujo de bytes para poder pasarlo de forma más fácil a una cinta magnética, en los viejos días donde se usaban cintas magnéticas para guardar la información. Eventualmente, TAR adquirió soporte para guardar en su lugar el flujo de datos en un archivo del disco duro y, hoy en día, sería rara la idea de guardar sobre cinta (a pesar de que hay gente que lo sigue haciendo).

Uno de los puntos clave sobre TAR es que, a diferencia de otros formatos como el ZIP o como el 7Z, TAR no comprime los archivos. Solamente los junta y les pone una serie de metadatos al principio del archivador para que luego se puedan extraer, es decir, separar y volver a dejar como múltiples archivos separados.

Para comprimir un archivo TAR hay que usar otra herramienta separada, como gzip, lzip o xz. Existen múltiples formatos de compresión porque cada uno fue desarrollado en una época distinta y trata de mejorar lo que ya existe. Por ejemplo, el último en aparecer es zstd, el cual promete grandes mejoras de rendimiento cuando se usa en centros de datos grandes.

Sin embargo, lo que hay que tener claro es que, a diferencia de ZIP, donde archivas y comprimes a la vez, en TAR son dos pasos separados. Si quieres crear una carpeta comprimida usando formatos libres, tendrías que:

  1. Juntar con TAR todos los archivos de un directorio en un mismo archivador (por ejemplo, datos.tar).
  2. Comprimir ese archivo (datos.tar), para convertirlo en datos.tar.gz, datos.tar.xz, datos.tar.bz2…
Esquema de la concatenación de un TAR y de su compresión por separado

Por lo general, la forma más correcta de tratar con un archivador comprimido es mantener las dos extensiones, para dejar claro que es un TAR comprimido con algún tipo de algoritmo. En este caso la extensión nos dirá qué tipo de algortimo tenemos que usar para descomprimir. Por ejemplo, .tar.gz nos dice que se trata de un tarball comprimido con gzip, .tar.xz que es un tarball comprimido con xz (LZMA), .tar.bz2 que está comprimido con Bzip2, etc.

Sin embargo, en muchas ocasiones nos vamos a encontrar que juntan ambas extensiones en una única por comodidad. Si somos capaces de entender que .tgz es lo mismo que .tar.gz, y que .txz es lo mismo que .tar.xz, estaremos bien.