Comando tail de Linux
El comando tail de Linux es una de las herramientas fundamentales de la línea de comandos. Principalmente, el comando se utiliza para mostrar las últimas líneas de un archivo (de texto) o para restringir la salida de un comando de Linux a un ámbito concreto. De esta manera, el comando tail de Linux pertenece a un conjunto de comandos al que también pertenece el comando head de Linux y los comandos ‘cat’ y ‘less’. Este conjunto de comandos de Linux se utiliza para mostrar el contenido de archivos de texto.
El comando tail de Linux forma parte de las GNU Core Utilities (Coreutils). Se trata de una colección de comandos contenidos en el sistema operativo de código abierto Linux fundamentales para su línea de comandos. Las Coreutils se publican bajo una licencia de código abierto y su descarga está disponible para una variedad de sistemas operativos diferentes.
¿En que se utiliza el comando tail de Linux?
La funcionalidad básica del comando tail de Linux es mostrar las últimas líneas de un archivo. Para ello, debes saber que los datos que se escriben en un archivo se van añadiendo al final, dejando, de esta manera, los más recientes al final. Es por esta razón que tail de Linux nos permite comprobar si se han añadido nuevos datos a un archivo. Por lo tanto, el comando tail de Linux suele usarse para analizar los archivos de registro y monitorizarlos.
Muchos programas, especialmente los servidores web como Apache o nginx escriben información sobre estados en los llamados archivos de registro. En el caso de los registros del servidor, los archivos contienen en cada línea una marca de tiempo, la URL del recurso solicitado y la dirección IP del solicitante entre otros.
Los archivos de registro crecen con cada petición de recurso al sistema. Para limitar el tamaño pasado un cierto punto, los archivos de registro suelen ser “rotados”. El archivo de registro se comprime y se archiva con un nuevo nombre. A continuación, se crea un nuevo archivo de registro vacío con el nombre original. Aquí tienes un resumen de los archivos de registro más usados en Ubuntu Linux:
Archivo de registro de Ubuntu-Linux | Explicación |
/var/log/auth.log | Registro de autorización de Linux |
/var/log/daemon.log | Registro daemon de Linux |
/var/log/debug | Registro debug de Linux |
/var/log/kern.log | Registro del kernel de Linux |
/var/log/syslog | Registro del sistema de Linux |
/var/log/apache2/access.log | Registro de accesos al contenido web del servidor web Apache2 |
/var/log/apache2/error.log | Registro de mensajes de error del servidor web Apache2 |
Uso del comando tail de Linux en la línea de comandos
El comando tail de Linux se introduce en la línea de comandos. Como es habitual, se introduce el nombre del comando seguido de parámetros opcionales. El comando concluye con el nombre o la ruta de uno o varios archivos. Veamos primero la notación genérica:
tail [parámetros] <archivos>
Sin parámetros, la notación del comando tail de Linux es más simple y queda de la siguiente manera:
tail <archivo>
Escrito de esta manera, el comando tail de Linux muestra las últimas diez líneas del archivo especificado. Esto es útil para ver los datos más recientes escritos en el archivo.
Parámetros básicos del comando tail de Linux
El comando tail de Linux puede ser modificado por medio de parámetros. Como parte de los coreutils de GNU, hay un formato largo para cada parámetro. Los parámetros más utilizados tienen también un formato abreviado, que se lleva usando desde siempre. Aquí tienes un resumen de los parámetros más usados:
Parámetro (formato corto / formato largo) | Explicación |
-n / --lines | Limita la respuesta únicamente a las últimas n líneas / Limita la respuesta únicamente a las líneas posteriores a la línea n |
-c / --bytes | Limita la respuesta únicamente a los últimos n bytes / Limita la respuesta únicamente a los bytes posteriores al byte n |
-q / --quiet, --silent | Cuando se usa con varios archivos, omite los nombres de los archivos |
-v / --verbose | Cuando se usa con varios archivos, fuerza la salida de todos los nombres de los archivos |
--help | Solicita ayuda sobre el comando |
--version | Solicita información sobre la versión del comando |
El comando tail de Linux está diseñado principalmente para ser usado con archivos de texto en el código ASCII. Para el código ASCII, un carácter corresponde exactamente a un byte. Si utilizas el parámetro ‘-c’ con el comando tail de Linux para archivos que usen el código Unicode puede producirse algún efecto secundario inesperado.
Parámetros avanzados del comando tail de Linux
Los parámetros básicos del comando tail de Linux, mostrados anteriormente, son análogos en su funcionamiento a los del comando head. Sin embargo, mientras que el comando head muestra el principio de un archivo, el comando tail de Linux muestra su final. Ahora bien, el comando puede hacer mucho más.
En particular, el comando tail de Linux proporciona una variedad de opciones para el seguimiento de los archivos en busca de cambios. El comando tail de Linux permite mostrar continuamente datos añadidos al final de un archivo. Por consiguiente, el comando es especialmente útil para el seguimiento de los archivos de registro. Este proceso también se conoce como “live tail”. Aquí tienes un resumen de los parámetros más usados:
Parámetro (formato corto / formato largo) | Explicación |
-f / --follow=[{name|descriptor}] | Monitoriza el archivo en busca de cambios y emite continuamente los nuevos datos escritos al final del archivo. Si no se especifica un valor después de ‘--follow=’, se utiliza ‘descriptor’ como valor por defecto. Esto mantendrá el live tail incluso si el archivo es renombrado o movido. |
-F | Es lo mismo que combinar los parámetros --follow=nombre --retry; el resultado es que el live tail seguirá funcionando incluso si el archivo original se elimina durante la rotación del registro y es sustituido por un nuevo archivo con el mismo nombre. |
-s / --sleep-interval=N | La salida que da el archivo al live tail se para durante el número de segundos especificado. |
--retry | Intenta reabrir un archivo no disponible en cuanto vuelva a estarlo. Es especialmente útil en combinación con el parámetro ‘--follow=nombre’ para continuar monitorizando el nuevo archivo generado con el mismo nombre tras la rotación de un archivo de registro. |
--pid=PID | Se suele utilizar en combinación con el parámetro -f, el resultado es que el comando tail finaliza cuando el proceso con el ID indicado termine. Resulta útil para abortar el live tail cuando el programa que está escribiendo en el archivo termine. |
Ejemplos de uso del comando tail de Linux
En la documentación de coreutils, el comando tail de Linux aparece en la sección “Output of parts of files” (Salida de parte de archivos). Piensa que en este caso “archivos” es un término muy amplio. El término “flujos de texto” es más preciso.
Siguiendo la filosofía de Unix, los comandos de la línea de comandos utilizan flujos de texto como formato universal de entrada y salida. El término “flujos de texto” hace referencia, sobre todo, a archivos, pero también la típica entrada y salida de la línea de comandos. Además, las “pipes”, llamadas “tuberías” en español, son de gran importancia. Permiten encadenar varios comandos. Para ello, la salida de un comando se transmite como entrada al siguiente comando.
La idea detrás de encadenar varios comandos se remonta, de nuevo, a la filosofía de Unix. En lugar de desarrollar comandos complejos para tareas completamente diferentes, existe un conjunto relativamente asequible de comandos generales. Siguiendo la máxima “do one thing, and do it well” (en español “haz una cosa, y hazla bien”), cada comando tiene una funcionalidad claramente definida. Los comandos utilizan flujos de texto como interfaz universal y pueden combinarse para crear soluciones nuevas.
En los siguientes ejemplos, al ejecutar el comando tail de Linux, vamos a utilizar las preposiciones de formato abreviado (‘-n’, en lugar de ‘--lines’, etc.). Si lees otros documentos o ejemplos de código, verás que es habitual usar el formato abreviado.
Ejemplos genéricos de uso del comando tail de Linux
Los siguientes ejemplos genéricos se basan en los parámetros básicos del comando tail de Linux presentados al principio. Para ver ejemplos que utilicen los parámetros más avanzados, consulta la sección sobre la monitorización de los archivos de registro que se encuentra más abajo.
La mayoría de los ejemplos mostrados en esa sección combinan el comando tail de Linux con uno o más comandos de Linux. Es aquí cuando son útiles las pipes mencionadas anteriormente, que permiten transmitir la salida de un comando a la entrada del siguiente en la cadena.
Usar el comando tail de Linux para mostrar el final de un archivo
En el caso más sencillo, utilizamos el comando tail de Linux para mostrar las últimas líneas de un archivo. Para probar esto, sustituye el marcador de posición ‘<archivo>‘ por el nombre o la ruta de un archivo de texto que exista en tu sistema. En este ejemplo utilizamos el parámetro -n y sacamos las tres últimas líneas de un archivo:
tail -n 3 <archivo>
A menudo es útil mantener un ojo en el contexto del archivo procesado con el comando tail de Linux. Para mostrar las líneas numeradas, primero procesamos el archivo con el comando nl (el nombre viene de “line numbering”— “numeración de líneas”) y canalizamos la salida de la pipe de nuevo al comando tail de Linux:
nl <archivo> | tail -n 3
Mostrar los últimos comandos utilizados en la línea de comandos
El comando history muestra los comandos introducidos anteriormente en la línea de comandos. Normalmente, uno solo se interesa por los últimos comandos ejecutados. Además, mostrar el historial de comandos al completo puede revelar datos sensibles. Aquí transmitimos la salida del comando history al comando tail de Linux y mostramos las últimas cinco líneas:
history | tail -n 5
Usar el comando tail de Linux para eliminar los archivos de copia de seguridad más antiguos de un directorio.
Veamos un ejemplo más complejo. Vamos a eliminar los diez archivos más antiguos de un directorio que contiene archivos de copia de seguridad. Para ello, utilizaremos cuatro comandos de Linux, que son ‘ls’, ‘tail’, ‘xargs’ y ‘rm’:
ls -t *.bak | tail | xargs rm
¿Qué ocurre exactamente aquí?
- El comando ‘ls’ muestra una lista de los archivos de un directorio
Con el parámetro ‘-t’, los archivos se ordenan por fecha de modificación. Los archivos más antiguos quedan al final de la lista.
Utilizamos el patrón de búsqueda ‘*.bak’ para la fuente de datos. Este es una extensión de archivo común para los archivos de copia de seguridad. También actúa como protección adicional, para que, al ejecutarlo, no borremos archivos importantes accidentalmente.
A través de la pipe transmitimos la lista de archivos al comando tail de Linux.
- Usando el comando tail de Linux sin especificar ningún parámetro mostramos los últimos diez archivos de la lista. Los nombres de los archivos que se muestran en pantalla son los más antiguos del directorio.
- El comando xargs precisa la entrega de una lista de archivos y el nombre de un comando. Xargs ejecutará el comando que se le indique y le alimentará la lista de archivos como argumentos.
En nuestro ejemplo, el comando tail de Linux nos devuelve un texto con varias líneas. Cada línea contiene el nombre de un archivo que se va a eliminar. A través de ‘xargs’, los nombres de los archivos se separan de sus líneas respectivas y se pasan como argumentos al comando rm.
- Utilizamos el comando rm para eliminar archivos en Linux. El comando rm borra los archivos que ha recibido en forma de argumentos.
Ten en cuenta, que los archivos borrados no se envían a la papelera, sino que se eliminan al instante.
Hay que tener cuidado al borrar archivos desde la línea de comandos de Linux. Para que puedas probar a usar los comandos de nuestro ejemplo sin preocupaciones, primero deberías crear un directorio con archivos de prueba. Esto lo puedes hacer ejecutando el siguiente código en la línea de comandos:
mkdir ~/Desktop/tail-test/
cd ~/Desktop/tail-test/
touch test-{1..100}.bak
A continuación, creamos un directorio de prueba ‘tail-test/’ en el escritorio y cambiamos al directorio. Después, creamos 100 archivos de prueba vacíos que van del ‘test-1.bak’ al ‘test-100.bak’. Finalmente, ejecutamos el código para eliminar los diez archivos más antiguos:
ls -t ~/Desktop/tail-test/*.bak | tail | xargs rm
Usar el comando Tail de Linux para monitorizar los archivos de registro del servidor en busca de cambios
Hasta ahora, hemos visto el funcionamiento general del comando tail de Linux. En los siguientes ejemplos, nos centramos en la monitorización en directo de los archivos de registro del servidor (“live tail”).
En estos ejemplos partimos del servidor web Apache2 con Ubuntu Linux. Allí, los archivos de registro se encuentran en el directorio ‘/var/log/apache2/’. En otras distribuciones de Linux, la ubicación puede ser otra. Lo mismo ocurre con otros servidores web, como el servidor web nginx.
Lo más probable es que solo el usuario root tenga acceso al directorio con los archivos de registro. En este caso tendrías que ejecutar los comandos con ‘sudo’.
Usar el comando tail de Linux para monitorizar un archivo de registro del servidor en busca de cambios
Una ejecución normal del comando tail de Linux muestra el número de líneas especificado una única vez. Si, a continuación, se añaden nuevos datos al final del archivo, el comando debe ejecutarse de nuevo. Para estos casos en concreto existen algunos parámetros avanzados que indican al comando que monitorice un archivo en busca de cambios y que muestre esos cambios continuamente.
Veamos cómo funciona utilizando como ejemplo el registro de acceso del servidor web Apache2. Ejecutamos el comando tail de Linux con el parámetro -f e introducimos la ruta y nombre del archivo de registro:
tail -f /var/log/apache2/access.log
Cuando se ejecuta de esta manera, los cambios en el registro de acceso se emiten continuamente. Si hay muchos accesos por unidad de tiempo, el método deja de ser práctico. El registro tendría cambios tan frecuentemente que el terminal se inundaría de datos. Si ocurre esto, pulsa la combinación de teclas “Ctrl+C” para cancelar la ejecución actual de la live tail.
Si ejecutamos el comando tail de Linux con el parámetro -f, se monitoriza el archivo especificado. Pero, si el archivo se elimina, el comando deja de mostrar los cambios. Como hemos explicado al principio, los archivos de registro se rotan periódicamente. Por lo tanto, se crea un nuevo archivo con el nombre antiguo. Para seguir monitorizando un archivo de registro a pesar de la rotación, utilizamos el parámetro -F:
tail -F /var/log/apache2/access.log
Usar el comando tail de Linux para monitorizar múltiples archivos de registro del servidor en busca de cambios.
Hasta ahora, solo hemos utilizado el comando tail de Linux para procesar un archivo. Sin embargo, el comando también permite monitorizar varios archivos a la vez. Aquí utilizamos el patrón de búsqueda ‘*.log’ para monitorizar continuamente todos los archivos con la extensión ‘.log’:
tail -F /var/log/apache2/*.log
Cuando procesamos varios archivos podemos ayudarnos de dos parámetros usados habitualmente. En primer lugar, podemos omitir la salida de los nombres de los archivos con el parámetro ‘-q’:
tail -q -F /var/log/apache2/*.log
Del mismo modo, podemos usar el parámetro ‘-v’ para forzar la salida de los nombres de los archivos. Se suele usar cuando el patrón de búsqueda devuelve un solo archivo:
tail -v -F /var/log/apache2/*.log
Usar del comando tail de Linux para monitorizar un archivo de registro del servidor en busca de cambios concretos
Hasta ahora hemos monitorizado un archivo de registro para detectar cualquier tipo de cambio. Sin embargo, es más común delimitar la salida a cambios específicos. Podemos usar el comando grep para limitar la salida de cambios del archivo de registro a un patrón de búsqueda. Aquí tienes un ejemplo genérico de su uso:
tail -F /var/log/apache2/access.log | grep <patrón>
Es muy común monitorizar el registro de un servidor para buscar el acceso de una dirección IP concreta. Esto nos puede servir para determinar si el ataque a un servidor ya ha terminado o está todavía en curso. En este ejemplo monitorizamos el registro de acceso del servidor web Apache para las entradas procedentes de la dirección IP ‘93.184.216.34’:
tail -F /var/log/apache2/access.log | grep '93.184.216.34'
Estamos utilizando la dirección IP del dominio de ejemplo ‘example.com’. Si se registra un acceso que contenga esta IP es muy probable que se trate de una dirección IP suplantada.
Veamos otro escenario común. En lugar de filtrar el registro de accesos en función de una dirección IP, monitorizamos los accesos a un recurso concreto. Un acceso al archivo ‘robots.txt’ indica que los bots de los motores de búsqueda están solicitando este recurso. De nuevo, vamos a utilizar el comando grep. Si queremos que muestre los nuevos accesos de los bots de motores de búsqueda, debemos ejecutarlo de esta manera:
tail -F /var/log/apache2/access.log | grep 'robots.txt'