El comando tail de Linux genera la última parte de los archivos. Hay una opción para mantener el archivo abierto para futuras entradas. Esto hace que sea muy útil trabajar con archivos de registro donde podemos verificar los registros en tiempo real cuando ocurre un evento.
1. Sintaxis del comando de cola de Linux
La sintaxis del comando tail es:
$ tail [OPTION]... [FILE]...
Todas las opciones y nombres de archivo son opcionales.
2. ¿Qué hará tail si no se proporciona ningún archivo?
Si no proporciona el nombre del archivo al final, o lo especifica como un guión (-), se lee la entrada estándar.
3. Lectura de las últimas 10 líneas de un archivo
Si no especificamos ninguna opción, la cola leerá las últimas 10 líneas de un archivo.
# tail error.log
2019-10-29 11:31:09.887840 [INFO] [16169] [APVH_recipes_Sulsphp73:]: locked pid file [/tmp/lshttpd/APVH_recipes_Suphp73.sock.pid].
2019-10-29 11:31:09.887968 [INFO] [16169] [APVH_recipes_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_recipes_Suphp73.sock
2019-10-29 11:31:09.896280 [INFO] [16169] [APVH_recipes_Sulsphp73:] add child process pid: 27035, procinfo: 0x2c5e2b0
2019-10-29 11:31:09.896396 [INFO] [16169] [APVH_recipes_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_recipes_Suphp73.sock.pid].
2019-10-29 11:31:17.182067 [INFO] [16169] [APVH_golangd_Sulsphp73:]: locked pid file [/tmp/lshttpd/APVH_golangd_Suphp73.sock.pid].
2019-10-29 11:31:17.182116 [INFO] [16169] [APVH_golangd_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_golangd_Suphp73.sock
2019-10-29 11:31:17.182991 [INFO] [16169] [APVH_golangd_Sulsphp73:] add child process pid: 27067, procinfo: 0x447cff0
2019-10-29 11:31:17.183048 [INFO] [16169] [APVH_golangd_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_golangd_Suphp73.sock.pid].
2019-10-29 11:31:20.641690 [INFO] [16169] [149.56.101.239:45604] [ACL] Access to context [/] is denied!
2019-10-29 11:31:27.245789 [INFO] [16169] [198.199.83.232:46876] [ACL] Access to context [/] is denied!
#
4. Opciones de comando de cola de Linux
Opción corta | Opción larga | Descripción |
---|---|---|
-c | –bytes=K | muestra los últimos K bytes del archivo. Podemos usar "-c +K" para generar bytes comenzando con el Kth de cada archivo. |
-f | –seguir[={nombre|descriptor}] | datos adjuntos de salida a medida que crece el archivo. Si especificamos -F, es lo mismo que “–follow=name –retry” |
-n | –lines=K | muestra las últimas K líneas, en lugar de las últimas 10; o use '-n +K' para generar una salida que comience con la línea Kth. |
-q | –silencio, –silencio | nunca mostrar encabezados con nombres de archivo |
–reintentar | siga intentando abrir un archivo si es inaccesible | |
-s | –sleep-interval=N | usado con -f para dormir durante aproximadamente N segundos (predeterminado 1.0) entre iteraciones. |
-v | –detallado | siempre generar encabezados dando nombres de archivo |
–versión | información de versión de salida y salida. |
- Si el primer carácter de K (el número de bytes o líneas) es un '+', imprima comenzando con el K-ésimo elemento desde el inicio de cada archivo; de lo contrario, imprima los últimos K elementos en el archivo.
- K puede tener un sufijo multiplicador:b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024, GB 1000*1000*1000, G 1024*1024*1024, etc. para T, P , E, Z, Y.
- Con –follow (-f), la cola sigue de forma predeterminada el descriptor del archivo, lo que significa que incluso si se cambia el nombre de un archivo con cola, la cola seguirá rastreando su final. Este comportamiento predeterminado no es deseable cuando realmente desea rastrear el nombre real del archivo, no el descriptor del archivo (por ejemplo, rotación de registros).
- Use –follow=nombre en ese caso. Eso hace que la cola rastree el archivo nombrado de una manera que se adapte al cambio de nombre, la eliminación y la creación.
5. Ejemplos de comandos de cola de Linux
Veamos algunos ejemplos del uso del comando de cola.
5.1) Limitar el número de líneas en la salida de cola
Podemos usar la opción -n o –lines para limitar el número de líneas en la salida final.
# tail -n 5 error.log
# tail --lines=5 error.log
Si usamos el prefijo + con el valor de la opción, la salida se iniciará desde ese número de línea en el archivo.
# wc -l error.log
27360 error.log
# tail -n +27358 error.log
2019-10-29 13:09:35.142604 [INFO] [16169] [APVH_javastr_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_javastr_Suphp73.sock
2019-10-29 13:09:35.144320 [INFO] [16169] [APVH_javastr_Sulsphp73:] add child process pid: 18132, procinfo: 0x367c520
2019-10-29 13:09:35.144389 [INFO] [16169] [APVH_javastr_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
# tail --lines=+27358 error.log
2019-10-29 13:09:35.142604 [INFO] [16169] [APVH_javastr_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_javastr_Suphp73.sock
2019-10-29 13:09:35.144320 [INFO] [16169] [APVH_javastr_Sulsphp73:] add child process pid: 18132, procinfo: 0x367c520
2019-10-29 13:09:35.144389 [INFO] [16169] [APVH_javastr_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
#
5.2) Limite el número de bytes en la salida final
Podemos usar la opción -c o –bytes para generar los bytes especificados desde el final del archivo.
# tail -c 100 error.log
[16169] [APVH_android_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_android_Suphp73.sock.pid].
# tail --bytes=100 error.log
[16169] [APVH_android_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_android_Suphp73.sock.pid].
#
Si usamos + con el valor de la opción, los datos del archivo de ese byte se enviarán a la consola.
# ls -ltr error.log
-rw-r--r--. 1 nobody nobody 3475359 Oct 29 13:15 error.log
# tail -c +3475350 error.log
ock.pid].
#
5.3) Comando cola de Linux con varios archivos
Podemos pasar varios nombres de archivo y la salida tendrá un encabezado con el nombre del archivo seguido de la salida.
# tail -n 2 error.log error.log.2019_10_27
==> error.log <==
2019-10-29 13:17:24.356633 [INFO] [16169] [APVH_golangd_Sulsphp73:] add child process pid: 19670, procinfo: 0x27af560
2019-10-29 13:17:24.356789 [INFO] [16169] [APVH_golangd_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_golangd_Suphp73.sock.pid].
==> error.log.2019_10_27 <==
2019-10-27 20:26:31.050022 [INFO] [16169] [176.9.99.9:34084] [ACL] Access to context [/] is denied!
2019-10-27 20:26:31.216835 [INFO] [16169] [176.9.99.9:34118] [ACL] Access to context [/] is denied!
#
Podemos usar la opción -q para una salida silenciosa. Es útil fusionar la salida de varios archivos.
# tail -n 2 -q error.log error.log.2019_10_27
2019-10-29 13:18:44.095709 [INFO] [16169] [APVH_javastr_Sulsphp73:] add child process pid: 19947, procinfo: 0x4312b50
2019-10-29 13:18:44.095766 [INFO] [16169] [APVH_javastr_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
2019-10-27 20:26:31.050022 [INFO] [16169] [176.9.99.9:34084] [ACL] Access to context [/] is denied!
2019-10-27 20:26:31.216835 [INFO] [16169] [176.9.99.9:34118] [ACL] Access to context [/] is denied!
#
5.4) Ver un archivo en busca de cambios
Podemos usar la opción -f para ver el archivo en busca de cambios adicionales. Esta es la opción más utilizada con el comando tail. Es útil para rastrear registros en tiempo real y depurarlos.
[root@li1197-217 logs]# tail -f error.log
2019-10-29 13:22:31.719103 [INFO] [16169] [APVH_cultwpc_Sulsphp73:] add child process pid: 20640, procinfo: 0x384a9a0
2019-10-29 13:22:31.719172 [INFO] [16169] [APVH_cultwpc_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_cultwpc_Suphp73.sock.pid].
2019-10-29 13:22:32.176946 [INFO] [16169] [APVH_android_Sulsphp73:]: locked pid file [/tmp/lshttpd/APVH_android_Suphp73.sock.pid].
2019-10-29 13:22:32.176979 [INFO] [16169] [APVH_android_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_android_Suphp73.sock
2019-10-29 13:22:32.177901 [INFO] [16169] [APVH_android_Sulsphp73:] add child process pid: 20645, procinfo: 0x2df6830
2019-10-29 13:22:32.177955 [INFO] [16169] [APVH_android_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_android_Suphp73.sock.pid].
2019-10-29 13:22:39.634710 [INFO] [16169] [APVH_javastr_Sulsphp73:]: locked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
2019-10-29 13:22:39.634755 [INFO] [16169] [APVH_javastr_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_javastr_Suphp73.sock
2019-10-29 13:22:39.641576 [INFO] [16169] [APVH_javastr_Sulsphp73:] add child process pid: 20677, procinfo: 0x286e3b0
2019-10-29 13:22:39.641694 [INFO] [16169] [APVH_javastr_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
También podemos ver varios archivos con la opción -f.
[root@li1197-217 logs]# tail -f error.log lsrestart.log
==> error.log <==
2019-10-29 13:22:31.719103 [INFO] [16169] [APVH_cultwpc_Sulsphp73:] add child process pid: 20640, procinfo: 0x384a9a0
2019-10-29 13:22:31.719172 [INFO] [16169] [APVH_cultwpc_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_cultwpc_Suphp73.sock.pid].
2019-10-29 13:22:32.176946 [INFO] [16169] [APVH_android_Sulsphp73:]: locked pid file [/tmp/lshttpd/APVH_android_Suphp73.sock.pid].
2019-10-29 13:22:32.176979 [INFO] [16169] [APVH_android_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_android_Suphp73.sock
2019-10-29 13:22:32.177901 [INFO] [16169] [APVH_android_Sulsphp73:] add child process pid: 20645, procinfo: 0x2df6830
2019-10-29 13:22:32.177955 [INFO] [16169] [APVH_android_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_android_Suphp73.sock.pid].
2019-10-29 13:22:39.634710 [INFO] [16169] [APVH_javastr_Sulsphp73:]: locked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
2019-10-29 13:22:39.634755 [INFO] [16169] [APVH_javastr_Sulsphp73:] remove unix socket for detached process: /tmp/lshttpd/APVH_javastr_Suphp73.sock
2019-10-29 13:22:39.641576 [INFO] [16169] [APVH_javastr_Sulsphp73:] add child process pid: 20677, procinfo: 0x286e3b0
2019-10-29 13:22:39.641694 [INFO] [16169] [APVH_javastr_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
==> lsrestart.log <==
Thu Oct 10 17:45:33 UTC 2019
restart, LSWS running: 1
Wed Oct 23 08:53:16 UTC 2019
restart, LSWS running: 1
Wed Oct 23 09:03:02 UTC 2019
restart, LSWS running: 1
También podemos especificar el número de líneas en la salida con la opción -f.
# tail -2f error.log
2019-10-29 13:28:46.086130 [INFO] [16169] [APVH_cultwpc_Sulsphp73:] add child process pid: 21976, procinfo: 0xd032210
2019-10-29 13:28:46.086193 [INFO] [16169] [APVH_cultwpc_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_cultwpc_Suphp73.sock.pid].
5.5) Usar el comando tail con pipe y grep
A veces nos interesan solo mensajes específicos en la salida de la cola. Podemos usar el comando tail con pipe y grep para filtrar los mensajes específicos en la salida.
# tail -100f error.log | grep 'denied'
2019-10-29 13:21:49.170651 [INFO] [16169] [159.65.53.153:38448] [ACL] Access to context [/] is denied!
2019-10-29 13:22:00.991330 [INFO] [16169] [182.71.209.203:22089] [ACL] Access to context [/] is denied!
2019-10-29 13:25:47.188167 [INFO] [16169] [79.137.42.145:36674] [ACL] Access to context [/] is denied!
2019-10-29 13:25:52.668213 [INFO] [16169] [162.144.60.165:52886] [ACL] Access to context [/] is denied!
5.6) Uso del comando tail para filtrar la salida de otro comando
Podemos usar el comando tail con otro comando para filtrar las líneas de salida. Es útil cuando solo estamos interesados en unas pocas líneas de la salida de un comando.
# ls -ltr | tail -n 3
-rw-r--r--. 1 nobody nobody 24406 Oct 23 09:08 error.log.2019_10_23.02
-rw-r--r--. 1 nobody nobody 10486279 Oct 27 20:26 error.log.2019_10_27
-rw-r--r--. 1 nobody nobody 3494794 Oct 29 13:29 error.log
#
# ls -ltr | tail -n +15
-rw-r--r--. 1 nobody nobody 10490954 Oct 21 09:42 error.log.2019_10_21
-rw-r--r--. 1 nobody nobody 10485856 Oct 22 07:44 error.log.2019_10_22
-rw-r--r--. 1 nobody nobody 10485809 Oct 22 14:16 error.log.2019_10_22.01
-rw-r--r--. 1 nobody nobody 5398751 Oct 23 08:29 error.log.2019_10_23
-rw-r--r--. 1 nobody nobody 61485 Oct 23 08:58 error.log.2019_10_23.01
-rw-r--r--. 1 root root 162 Oct 23 09:03 lsrestart.log
-rw-r--r--. 1 nobody nobody 24406 Oct 23 09:08 error.log.2019_10_23.02
-rw-r--r--. 1 nobody nobody 10486279 Oct 27 20:26 error.log.2019_10_27
-rw-r--r--. 1 nobody nobody 3499801 Oct 29 13:34 error.log
5.7) Impresión de la versión de cola
Podemos usar –version para imprimir la versión del comando final.
# tail --version
tail (GNU coreutils) 8.22
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later .
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Paul Rubin, David MacKenzie, Ian Lance Taylor,
and Jim Meyering.
#
5.8) salida detallada del comando tail
Si usamos la opción detallada, la salida tendrá un encabezado con el nombre del archivo.
# tail -v -n 2 error.log
==> error.log <==
2019-10-29 13:39:30.769561 [INFO] [16169] [APVH_javastr_Sulsphp73:] add child process pid: 24454, procinfo: 0x405b840
2019-10-29 13:39:30.769618 [INFO] [16169] [APVH_javastr_Sulsphp73:]: unlocked pid file [/tmp/lshttpd/APVH_javastr_Suphp73.sock.pid].
#
6. Conclusión
El comando tail de Linux es muy útil para depurar mensajes de registro en tiempo real. Es una gran herramienta para que los desarrolladores trabajen con archivos de registro.
Referencia :Página de Wikipedia