Redireccionamiento y tuberias

De XTech Capacitacion

Tabla de contenidos

Herramientas importantes

Un sistema Linux cuenta con gran cantidad de herramientas, cada una de las cuales realiza una labor muy específica pero rápidamente y bien; les presentamos unas cuantas típicamente usadas para procesar texto plano.

Junto con cada herramienta presentamos algunas de sus opciones y ejemplos de su uso (la documentación completa de cada herramienta puede consultarse en la página del manual o en la documentación info). Éstas complementan algunas de las ya vistas anteriormente.

Ejecución de programas en Linux

La ejecución de programas (archivos) en Linux es solo una cuestión de permisos, por lo que podremos ejecutar cualquiera que tenga activado el bit de ejecución, por lo menos, en el usuario (si es un archivo nuestro).

Para eso haremos uso del comando chmod a+x archivo, si por ejemplo queremos que sea ejecutable para todos.

Una vez que ya es ejecutable, podemos solo escribir su nombre, precedido de la ruta al mismo para que se ejecute. Si estamos en el mismo directorio que el archivo será:

$ ./archivo

Control de procesos

Esto es algo muy interesante de manejar bien, puesto que son los trucos que nos hacen la vida más fácil desde la consola de comandos. Se trata de los atajos de teclado.

Atajo Acción que realiza
^ dEnvía un EOF al shell que causa una salida del modo edición. También sirve como atajo del comando exit, que permite salir de la sesión actual.
^ cTermina el proceso que esté en ejecución abruptamente.
^ zPone el proceso en ejecución a dormir (como una pausa). No lo termina.
^ lRealiza un clear pero manteniendo la linea en la que fue pulsada esta combinación de teclas.
^ rEl bash entra en el modo 'reverse-i-search', que se utiliza para buscar comandos que fueron ejecutados anteriormente. En este modo el usuario puede ir escribiendo parte de la linea de comandos que esta buscando, y el bash va mostrando la línea de comandos que el cree la más adecuada. Una vez has encontrado la que buscabas, enter.
^ tIntercambia dos letras contiguas. Por ejemplo, si se escribe apt-gte, solo hay que colocarse después o en la 'e' y aplicarlo. Resultado: apt-get
^ sBloquea el shell.
^ qDesbloquea el shell. También sirve para salir del man, info y top, como ejemplos.

top

Códigos de estado de procesos

D Dormido en forma ininterrumpible
R Corriendo o en cola
S Dormido a la espera de un evento
T Parado momentaneamente a la espera de uan señal de control
W Paginado
X Muerto (nunca debería aparecer uno de estos)
Z Proceso "zombi"

nl, head, tail

Permiten ver uno o más archivo o parte de uno o más archivos. Complementan el uso de cat, more y less que ya vimos antes.

En el caso de nl, nos muestra un cat, pero con los números de línea a la izquierda de cada línea. Esto nos puede servir para identificar alguna parte de un texto que queramos tratar luego.

$ nl archivo.txt
    1  una línea
    2  otra
    3  y otra más
$ cat archivo.txt
una línea
otra
y otra más

En el caso de head y tail, nos muestran las primeras o las últimas 10 líneas de uno o más archivos, respectivamente. Veamos el ejemplo en un mismo archivo:

$ cat archivo.txt
La criptografía es la
disciplina de la computación
que trata de la transmisión
y almacenamiento de datos
de manera que no puedan ser
comprendidos ni modificados
por terceros.

La criptografía cuántica
es una de las
primeras aplicaciones
de la computación
cuántica cercana a una
fase de producción masiva.

La criptografía cuántica
garantiza absoluta
confidencialidad de la
información transmitida
por fibras ópticas,
almacenando información
en el elemento
constituyente de la luz,
el fotón.
$ head archivo.txt
La criptografía es la
disciplina de la computación
que trata de la transmisión
y almacenamiento de datos
de manera que no puedan ser
comprendidos ni modificados
por terceros.

La criptografía cuántica
es una de las
$ tail archivo.txt
La criptografía cuántica
garantiza absoluta
confidencialidad de la
información transmitida
por fibras ópticas,
almacenando información
en el elemento
constituyente de la luz,
el fotón.

split

Divide un archivo empleando como criterio el tamaño del mismo. Acepta como opciones (-b) bytes o (-l) líneas.

Por ejemplo, para dividir un archivo grande en partes de 100000 bytes:

$ split -b 100000 grande

Las partes quedarán en archivos con nombres como xaa, xab, etc. Sin desechar el archivo original!

Con el ejemplo anterior, se vería así:

$ split -l 4 archivo.txt
$ ls
archivo.txt
xaa
xab
xac
xad
xae
xaf
$ cat xaf
almacenando información
en el elemento
constituyente de la luz,
el fotón.

sort

Por defecto, ordena las líneas de un archivo, con la opción -m mezcla dos archivos ordenados y con la opción -c verifica que un archivo esté ordenado.

Al ordenar puede considerar las líneas completas, considerarlas números enteros (-n) o flotantes (-g), considerarlas meses (-M) o dividirlas en campos y emplear algunos campos como llaves de ordenamiento (opción -k para especificar llaves y -t para cambiar separador de campos).

En las comparaciones puede ignorar diferencias entre mayúsculas y minúsculas con la opción -f, puede ordenar de mayor a menor con la opción -r (por defecto ordena de menor a mayor) y puede eliminar líneas repetidas con la opción -u.Por ejemplo para ordenar por líneas el archivo nombres.txt:

$ sort nombres.txt
Acuña Rolando
Gomez Claudio
Perez José
Rivero Jacinto

si cada línea del archivo nombres.txt tiene el apellido y después el nombre de una persona separados por espacios, puede ordenarse por nombre con:

$ sort -k 2 nombres.txt
Gomez Claudio
Rivero Jacinto
Perez José
Acuña Rolando

Es importante entender que sort no guarda el ordenamiento, solo muestra por la stdout la lista ordenada.

wc

Cuenta cantidad de palabras, líneas y caracteres en uno o más archivos.

Por defecto presenta los tres datos por cada archivo que reciba y después presenta las sumas. Con la opción -c presenta la cuenta de palabras, con -l la cuenta de líneas, con -w la cuenta de palabras y con -L la longitud de la línea más larga.

Para los archivos de ejemplo anteriores:

$ wc nombres.txt
4  8 54 nombres.txt
$ wc archivo.txt
25  72 513 archivo.txt

Siempre el orden de la salida es:

Líneas  Palabras  Bytes  Nombre_de_archivo

Tuberias

Podríamos representar cada programa como una caja negra que tiene una entrada y una salida que se pueden unir entre ellos.

Debido a que la entrada por defecto es el teclado y la salida por defecto
es terminal, graficaremos cuando sea necesario ambos.

El ejemplo que utilizamos se encuentra esquematizado en la figura

Imagen:ESproceso.png

Siendo la entrada estándar el teclado y la salida estándar el terminal o por simplicidad la pantalla.

Vamos a suponer un caso ficticio donde necesitamos todas las definiciones de cada palabra en un texto. Primero las ordenamos alfabéticamente, luego utilizamos un comando ficticio llamado diccionario que toma palabras de la entrada estándar y las reescribe junto a su significado en la salida estándar.

Su esquema se ve en la figura

Imagen:Tuberia.png

En este caso nombramos por separado las entradas y salidas estándares de los dos programas, pero la unión entre ambos programas se puede considerar como un sólo tubo.

En ese tubo, el flujo está en un estado intermedio, donde está ordenado, pero no tiene las definiciones de diccionario.

En la línea de comandos esto se escribe de la siguiente manera:

$ sort | dicccionario

Donde el caracter " | " representa la conexión entre la salida estándar de un programa y la entrada estándar de otro.

Con este fuerte y simple concepto se pueden concatenar gran cantidad de programas como si fuera una línea de producción en serie para generar resultados complejos.

Para mejorar nuestro ejemplo sacaremos las palabras repetidas, antes de mostrarlas con definiciones. Suponiendo que exista un programa llamado sacar-repetidas, la línea de comando sería:

$ sort | sacar-repetidas | diccionario

Simple, utilizando herramientas sencillas logramos algo un poco más complicado. El inconveniente que tenemos en este ejemplo es que hay que escribir aquello a procesar. Normalmente queremos utilizar archivos como entrada de nuestros datos.

Es necesario un comando que envíe a la salida estándar un archivo, así se procesa como la entrada estándar del sort y continúa el proceso normalmente. Este comando es cat. La sintaxis es simple

cat nombre-de-archivo

Quedando nuestro ejemplo:

$ cat archivo.txt | sort | sacar-repetidas | diccionario

... esto crea un glosario de las palabras que se encuentren en archivo.txt

La combinación de comandos es incalculable y brinda posibilidades enormes. Veamos algunos ejemplos.

En el caso que se quieran buscar procesos con el string http:

$ ps ax | grep http
3343 ?        S      0:00 httpd -DPERLPROXIED -DHAV
3344 ?        S      0:00 httpd -DPERLPROXIED -DHAV
3975 ?        S      0:00 httpd -DPERLPROXIED -DHAV
12342 pts/6    S      0:00 grep http

Si queremos eliminar la ultima linea podemos volver a usar grep con la opcion -v

$ ps ax | grep http | grep -v grep
3343 ?        S      0:00 httpd -DPERLPROXIED -DHAV
3344 ?        S      0:00 httpd -DPERLPROXIED -DHAV
3975 ?        S      0:00 httpd -DPERLPROXIED -DHAV

Se pueden filtrar las líneas que contengan la palabra linux del archivo arch1.txt y luego mostrarlas en un paginador como less.

$ cat arch1.txt | grep linux | less

Podemos enviar los resultados por correo a un amigo, con un asunto que diga "Tu archivo".

$ cat arch1.txt | grep linux | mail -s 'Tu archivo' amigo@email.com

Redirección

En repetidas ocaciones en la vida de un sistema es mejor tener todo en archivos, ya sea para guardar algún historial o para automatizar ciertas funciones dentro de scripts.

Para almacenar o sacar información de archivos y vincularlas con entradas o salidas estándares se utilizan las Redirecciones.

La redirección se expresa con los símbolos "Mayor" > y "Menor" <. Y se pueden utilizar en forma simple o doble.

Utilizando el comando cat se puede hacer una copia de arch1.txt a arch2.txt utilizando redirección.

$ cat arch1.txt > arch2.txt

O se puede redireccionar un archivo para visualizarlo con el comando less.

$ less < arch1.txt

Redirección de escritura

Para escribir un archivo se utiliza >. Hay que tener mucho cuidado de no borrar un archivo sobreescribiéndolo. Cuando se utilizan redirecciones, debido a su utilidad en los scripts, "no se realizan confirmaciones".

Si el archivo a escribir ya existe desde antes, el redireccionador > lo sobreescribe con flujo de texto nuevo.

En cambio el operador >> realiza un agregado de texto en el flujo existente.

No hay nada mejor que un ejemplo clarificador:

$ escribe-en-salida-estandar > archivo.txt 

El (falso) comando escribe-en-salida-estándar justamente hace eso, escribe unas cuantas cosas en salida estándar.

Puede ser un comando ls, un comando cal (calendario) o cualquier comando antes visto, así como también una combinación de comandos por tuberías.

En este punto, el contenido de archivo.txt es lo mismo que saldría en pantalla. Si ejecutamos otro comando redireccionado a archivo.txt (nuevamente), éste pierde su contenido y el resultado de la operación pasa a estar en el mismo.

Cuando se necesita tener una lista de acontecimientos, no se quiere que un acontecimiento nuevo borre a todos los anteriores. Para lograr esto agregamos en vez de sobreescribir.

$ echo Este es el acontecimiento Nro. 1 > bitacora.log
$ echo Este es el segundo acontecimiento >> bitacora.log

Va a escribir dos líneas en el archivo bitacora.log sin eliminar nada.

Ejemplo: Si queremos combinar el ejemplo de las tuberías con lo aprendido recientemente podríamos escribir:

$ cat archivo.txt | sort | sacar-repetidas | diccionario >> glosario.txt

Redirección de lectura

Para la lectura es el símbolo menor < y se utiliza de la siguiente manera:

$ comando-que-acepta-stdin < archivo-de-entrada.txt

Como por ejemplo:

$ mail usuario1@micolegio.edu.ar usuario2@micolegio.edu.ar < correo.txt

Dónde correo.txt podría ser un archivo que se genere automáticamente... así como su contenido.

Otra facilidad para redireccionar entrada estándar es <<, que después de un comando, permite ingresar, por teclado, un texto que se constituirá en la entrada estándar.

A continuación de << debe ponerse una palabra, que indicará fin de entrada (en nuestro ejemplo, chau). La entrada estándar constará de las líneas que se digiten a continuación hasta la primera que contenga sólo la palabra que indicaba fin de entrada. Por ejemplo:

$ sort <<chau
> Perú
> Argentina
> Brasil
> chau
Argentina
Brasil
Perú

ordenará las palabras dadas (excepto chau que indica el fin de la entrada). Así, << es equivalente a editar un archivo y después redireccionarlo a la entrada estándar de un programa.

Combinaciones de teclas

[Ctrl]+[Alt]+[Del] 	

Shutdown. Apaga el sistema de forma organizada desde una terminal texto.

[Ctrl]+[Alt]+[F1] 

Cambia a la primera terminal de texto.

[Ctrl]+[Alt]+[Fn]

Cambia a la terminal de texto numero n (n=1,...,6)

[Ctrl]+[Alt]+[F7]

Cambia a la primera terminal X (si se esta usando alguna)

[Ctrl]+[Alt]+[Fn]

Cambia a la terminal X numero n (n=7,...,12)

[Tab]

Auto-completa el nombre de un mandato, archivo, directorio, programa. Cuando trabajamos en una terminal texto.

[ArrowUp]

(Flecha arriba) Va editando la historia de mandatos que hemos escrito anteriormente en terminal texto.

[Shift][PgUp]

Scroll la salida de la terminal hacia arriba, en terminal texto.

[Shift][PgDown]: 	

Scroll la salida de la terminal hacia abajo, en terminal texto.

[Ctrl]+c

Termina el proceso actual. Si no esta corriendo de fondo

[Ctrl]+d

Termina la terminal actual. También es la combinación para el comando exit.

[Ctrl]+s

Para la transferencia a la terminal.

[Ctrl]+z 

Manda el proceso actual a correr de fondo.

Ejercicios

Enunciado 1

Con los comandos aprendidos, mostrar de un directorio de varios archivos, los primeros 10.

Resolución

$ ls | head

Enunciado 2

Modificar el ejercicio anterior, para mostrar los 10 archivos de mayor tamaño, ordenados alfabéticamente.

Resolución

$ ls -l --sort=size | head

o

$ ls -lS | head

Enunciado 3

En un directorio con varios archivos, mostrar sólo los que tienen una determinada terminación. Como por ejemplo .txt utilizando grep y find.

Resolución

$ ls | grep *.txt

o

$ find ~ -name *.txt

Enunciado 4

Utilizando find o una composición de varios comandos por tuberías, mostrar sólo los enlaces simbólicos existentes, en caso de no poseer, crear varios en varios subdirectorios con el comando ln.

Resolución

 $ ls -p | grep @

Bibliografía

http://es.tldp.org/COMO-INSFLUG/COMOs/Bash-Prog-Intro-COMO/Bash-Prog-Intro-COMO-3.html
http://es.tldp.org/htmls/cursos.html
Herramientas personales