La mayoría del trabajo de línea de comandos se realiza sobre archivos. En esta sección discutimos cómo mirar y filtrar el contenido de archivos, tomar la información necesaria de los archivos utilizando un único comando, y clasificar el contenido de archivos.
Estos comandos tienen casi la misma sintaxis: nombre_del_comando [opciones] [archivo(s)], y se pueden usar en una tubería. Todos se utilizan para imprimir parte de un archivo de acuerdo con ciertos criterios.
El utilitario cat concatena archivos imprimiendo los resultados en la salida estándar. Este es uno de los comandos más ampliamente utilizados. Usted puede usar:
# cat /var/log/mail/info |
para imprimir, por ejemplo, el contenido del archivo de registro de un demonio de correo a la salida estándar[16]. El comando cat tiene una opción muy útil (-n) que le permite escribir los números de las líneas.
Algunos archivos, como los archivos de registro de los demonios (si es que están corriendo) por lo general tienen un tamaño enorme[17] y no es muy útil imprimirlos por completo en la pantalla. Por lo general Usted sólo necesita ver algunas líneas del archivo. Puede utilizar el comando tail para esto. El comando siguiente imprimirá, de manera predeterminada, las últimas 10 líneas del archivo /var/log/mail/info:
# tail /var/log/mail/info |
Puede usar la opción -n para mostrar las últimas N líneas de un archivo. Por ejemplo, para mostrar las últimas 2 líneas ingrese:
# tail -n2 /var/log/mail/info |
El comando head es similar a tail, pero imprime las primeras líneas de un archivo. El siguiente comando imprimirá, de manera predeterminada, las primeras 10 líneas del archivo /var/log/mail/info:
# head /var/log/mail/info |
Al igual que con tail Usted puede usar la opción -n para especificar la cantidad de líneas a imprimir. Por ejemplo, para imprimir las primeras 2 ingrese:
# head -n2 /var/log/mail/info |
También puede usar estos comandos juntos. Por ejemplo, si desea mostrar sólo las líneas 9 y 10, puede usar un comando donde primero el comando head va a seleccionar las primeras 10 líneas de un archivo y pasarlas a través de una tubería al comando tail.
# head /var/log/mail/info | tail -n2 |
La última parte luego seleccionará las últimas 2 líneas y las imprimirá en la pantalla. De la misma manera, puede seleccionar la línea número 20, contada desde el final de un archivo:
# tail -n20 /var/log/mail/info | head -n1 |
En este ejemplo, le decimos a tail que seleccione las últimas 20 líneas y las pase por una tubería a head. Luego, el comando head imprime la primer línea de los datos obtenidos.
Supongamos que deseamos imprimir el resultado del último ejemplo en la pantalla y, a la vez, guardarlo en el archivo resultados.txt. El utilitario tee nos puede ayudar. La sintaxis del mismo es:
tee [opciones] [archivo] |
Ahora podemos cambiar el comando anterior de esta manera:
# tail -n20 /var/log/mail/info | head -n1 | tee resultados.txt |
Tomemos otro ejemplo. Deseamos seleccionar las últimas 20 líneas, guardarlas en el archivo resultados.txt, pero imprimir en pantalla sólo la primera de las 20 líneas seleccionadas. Entonces, deberíamos teclear:
# tail -n20 /var/log/mail/info | tee resultados.txt | head -n1 |
El comando tee posee una opción útil (-a) que le permite añadir datos a un archivo existente.
Volvamos al comando tail. Por lo general los archivos de registro varían dinámicamente debido a que el demonio asociado a dicho registro constantemente añade acciones y eventos al archivo de registro. Entonces, si desea mirar interactivamente los cambios al archivo de registro puede aprovechar la opción -f:
# tail -f /var/log/mail/info |
En este caso, todos los cambios en el archivo /var/log/mail/info se imprimirán de inmediato en la pantalla. Utilizar el comando tail con la opción -f es muy útil cuando desea saber cómo funciona su sistema. Por ejemplo, mirando a través del archivo de registro /var/log/messages, puede estar al tanto con los mensajes del sistema y varios demonios.
En la próxima sección veremos cómo podemos utilizar grep como filtro para separar los mensajes de Postfix de aquellos mensajes que provienen de otros servicios.
Ni el acrónimo (“General Regular Expression Parser”, Analizador General de Expresiones Regulares), ni el nombre son muy intuitivos, pero su uso es simple. grep busca el patrón pasado como argumento en uno o más archivos. La sintaxis es:
grep [opciones] <patrón> [uno o más archivos] |
Si se mencionan varios archivos, los nombres de los mismos precederán a cada línea que muestra los resultados que se corresponden con el criterio de búsqueda. Use la opción -h para ocultar estos nombres; use la opción -l para obtener sólo los nombres de archivo en los cuales se cumple la condición de búsqueda. El patrón es una expresión regular, aunque generalmente consiste en una palabra simple. Las opciones usadas más frecuentemente son las siguientes:
-i: realizar una búsqueda que ignore la capitalización. (es decir, que ignore la diferencia entre las mayúsculas y las minúsculas);
-v: búsqueda inversa. Mostrar las líneas que no se corresponden con el patrón;
-n: mostrar, para cada línea encontrada, el número de línea;
-w: le dice a grep que el patrón debe corresponderse con una palabra completa, es decir debe aparecer tal cual y no como parte de otra palabra.
Volvamos entonces a analizar el archivo de registro del demonio de correo. Deseamos encontrar todas las líneas en el archivo /var/log/mail/info que contengan el patrón “postfix”. Entonces tecleamos este comando:
# grep postfix /var/log/mail/info |
El comando grep se puede utilizar en una tubería. Por lo tanto, podemos obtener el mismo resultado que en el ejemplo previo haciendo esto:
# cat /var/log/mail/info | grep postfix |
Si deseamos encontrar todas las líneas que no contienen el patrón “postfix”, deberíamos usar la opción -v:
# grep -v postfix /var/log/mail/info |
Supongamos que deseamos encontrar todos los mensajes acerca de correos enviados satisfactoriamente. En este caso tenemos que filtrar todas las líneas que fueron añadidas al archivo de registro por el demonio de correo (contiene el patrón “postfix”) y deben contener un mensaje acerca del envío satisfactorio (“status=sent”):
# grep postfix /var/log/mail/info | grep status=sent |
En este caso se utiliza a grep dos veces. Esto está permitido, pero no es muy elegante. Podemos obtener el mismo resultado utilizando el utilitario fgrep. Primero, debemos crear un archivo que contiene los patrones escritos en una columna. Se puede crear tal archivo de la manera siguiente (usamos el nombre patrones.txt):
# echo -e 'status=sent\npostfix' > ./patrones.txt |
Luego llamamos al comando siguiente donde usamos el archivo patrones.txt con una lista de patrones y el utilitario fgrep en vez de la “doble llamada” a grep:
# fgrep -f ./patrones.txt /var/log/mail/info |
El archivo ./patrones.txt puede tener tantos patrones como Usted desee. Cada uno tiene que estar tecleado en una única línea. Por ejemplo, para seleccionar los mensajes acerca de los envíos satisfactorios de correo a peter@mandrakesoft.com, será suficiente añadir esta dirección electrónica en nuestro archivo ./patrones.txt ejecutando el comando siguiente:
# echo 'peter@mandrakesoft.com' >> ./patrones.txt |
Está claro que puede combinar grep con tail y head. Si deseamos encontrar los mensajes sobre los últimos correos enviados a peter@mandrakesoft.com, excepto el último, tecleamos:
# fgrep -f ./patrones.txt /var/log/mail/info | tail -n2 | head -n1 |
Aquí aplicamos el filtro descrito arriba y colocamos el resultado en una tubería para los comandos tail y head. Los mismos seleccionan los últimos valores de los datos, excepto el último.
El comando wc (Word Count, Cuenta de palabras) se usa para calcular la cantidad de cadenas y palabras en archivos. También es útil para contar bytes, caracteres, y la longitud de la línea más larga. Su sintaxis es:
wc [opciones] [archivo(s)] |
Las siguientes opciones son útiles:
El comando wc imprime la cantidad de líneas nuevas, palabras y caracteres de manera predeterminada. Aquí tiene algunos ejemplos de uso:
Si deseamos encontrar la cantidad de usuarios en nuestro sistema, podemos teclear:
$wc -l /etc/passwd |
Si deseamos saber la cantidad de CPUs en nuestro sistema, tecleamos:
$grep "model name" /proc/cpuinfo | wc -l |
En la sección anterior obtuvimos una lista de mensajes acerca de los correos enviados satisfactoriamente a las direcciones listadas en nuestro archivo ./patrones.txt. Si deseamos saber la cantidad de dichos mensajes, podemos enviar los resultados de nuestro filtro por una tubería al comando wc:
# fgrep -f ./patrones.txt /var/log/mail/info | wc -l |
Aquí tiene la sintaxis de este poderoso utilitario de clasificación[18]:
sort [opciones] [archivo(s)] |
Consideremos clasificar parte de el archivo /etc/passwd. Como puede ver este archivo no está clasificado:
$ cat /etc/passwd |
Deseamos clasificarlo por el campo login. Entonces tecleamos:
$ sort /etc/passwd |
El comando sort clasifica datos de manera ascendente comenzando por el primer campo (en nuestro caso, el campo login) de manera predeterminada. Si deseamos clasificar los datos de manera descendente, usamos la opción -r:
$ sort -r /etc/passwd |
Cada usuario tiene su propio UID escrito en el archivo /etc/passwd. Clasifiquemos un archivo de manera ascendente con el campo UID:
$ sort /etc/passwd -t":" -k3 -n |
Aquí utilizamos las siguientes opciones de sort:
Se puede hacer lo mismo de manera inversa:
$ sort /etc/passwd -t":" -k3 -n -r |
Note que sort tiene dos opciones importantes:
Finalmente, si deseamos encontrar el usuario con el mayor UID podemos usar el comando siguiente:
$ sort /etc/passwd -t":" -k3 -n | tail -n1 |
donde clasificamos al archivo /etc/passwd de manera ascendente de acuerdo a la columna UID, y enviamos el resultado por medio de una tubería al comando tail que imprime el primer valor de la lista clasificada.
[16] Algunos ejemplos de esta sección están basados en trabajo real con archivos de registro de algunos servidores (servicios, demonios). Debe asegurarse que syslogd (permite el registro de los demonios) y el demonio correspondiente (en este ejemplo Postfix) estén activos, y que Usted trabaja como root. Por supuesto, siempre puede aplicar nuestros ejemplos a otros archivos.
[17] Por ejemplo, el archivo /var/log/mail/info contiene información acerca de todos los correos enviados, mensajes acerca de la recuperación de correo por parte de los usuarios con el protocolo POP, etc.
[18] Discutimos a sort brevemente aquí debido a que se podrían escribir libros completos acerca de sus características.