Página siguiente Página anterior Índice general

7. Comunicación entre procesos

Unix provee una serie de mecanismos para poder intercomunicar procesos

Se denomina proceso a un programa en ejecución
, como parte de la estrategia de combinar el uso de herramientas simples para poder resolver problemas complejos.

7.1 Entrada y salida estándar

La mayoría de los programas de Unix toman (leen) sus datos de entrada de la llamada “entrada estándar” y envían sus resultados (escriben) a la “salida estándar” (a menudo abreviadas como “stdin” y “stdout” respectivamente). Usualmente el sistema está configurado de forma que la entrada estándar es el teclado y la salida estándar la pantalla (recordemos que al teclado y la pantalla se los denomina comunmente “consola”).

Veamos un ejemplo con el comando cat. Normalmente cat lee datos de los archivos cuyos nombres se pasan como argumentos en la línea de comandos y envía estos datos directamente a la salida estándar. Luego, al ejecutar la orden:

/home/diego/articulos$ cat historia tesis

se mostrará por pantalla el contenido del archivo historia seguido por el contenido del archivo tesis.

Si cat no recibe nombres de archivos como parámetros, leerá datos de stdin y los enviará a stdout. Veamos un ejemplo:

/home/diego/articulos$ cat

Hola !!!

Hola !!!

Adiós.

Adiós.

[Ctrl]+[D]

/home/diego/articulos$

Como puede verse, cada línea que el usuario teclea (en letra itálica) es inmediatamente reenviada al monitor por cat. Cuando están leyendo datos, los procesos reconocen el fin de la entrada al recibir el carácter EOT (“end-of-text”, fin de texto). Normalmente es generado con la combinación de teclas [Ctrl]+[D].

Veamos otro ejemplo. El comando sort toma como entrada líneas de texto (al igual que cat, leerá desde stdin si no se le proporcionan nombres de archivos en la línea de comandos), y devuelve la salida ordenada por stdout. Probemos lo siguiente:

/home/diego/articulos$ sort

bananas

manzanas

duraznos

[Ctrl]+[D]

bananas

duraznos

manzanas

/home/diego/articulos$

7.2 Redirigiendo la entrada y salida

Ahora, supongamos que queremos que la salida de sort vaya a un archivo llamado compras en vez de a la pantalla. El intérprete de comandos nos permite redirigir la salida estándar a un archivo usando el símbolo “>”. Veamos como funciona:

/home/diego/articulos$ sort > compras

bananas

manzanas

duraznos

[Ctrl]+[D]

/home/diego/articulos$

Como podemos ver, el resultado de sort no se muestra por pantalla, en su lugar es escrito en el archivo compras. Veamos ahora su contenido:

/home/diego/articulos$ cat compras

bananas

duraznos

manzanas

/home/diego/articulos$

Supongamos ahora que tenemos nuestra lista desordenada original en el archivo cosas. Una forma de ordenar la información y escribirla en un archivo podría ser darle a sort el nombre del archivo a leer en lugar de la entrada estándar y redirigir la salida estándar como acabamos de hacer:

/home/diego/articulos$ sort cosas > compras

/home/diego/articulos$ cat compras

bananas

duraznos

manzanas

/home/diego/articulos$

Hay otra forma de hacer esto. No sólo puede ser redirigida la salida estándar, también puede ser redirigida la entrada estándar usando el símbolo “<”.

/home/diego/articulos$ sort < cosas

bananas

duraznos

manzanas

/home/diego/articulos$

Las órdenes “sort < cosas” y “sort cosas” tienen el mismo efecto, pero esto nos permite ver que el intérprete de comandos es quien maneja las redirecciones. sort no recibe el nombre del archivo a leer, desde su punto de vista, está leyendo datos de la entrada estándar como si fueran ingresados desde el teclado.

Esto introduce el concepto de “filtro”. Un filtro es un programa que lee datos de la entrada estándar, los procesa de alguna forma y devuelve el resultado por la salida estándar. Usando la redirección, tanto la entrada estándar como la salida estándar pueden ser radirigidas a archivos. sort es un filtro simple: ordena los datos de entrada y envía el resultado a la salida estándar. cat es incluso más simple, no hace nada con los datos de entrada, simplemente los envía a la salida tal como los recibe.

7.3 Redirección no destructiva

El uso de “>” para redirigir la salida a un archivo es destructivo. En otras palabras, la orden:

/home/diego/articulos$ ls > listado

sobreescribe el contenido del archivo listado. Si en su lugar, usamos los símbolos “>>”, la salida será añadida al final del archivo nombrado, en lugar de ser sobrescrito (creándolo, si este no existiera). El comando:

/home/diego/articulos$ ls >> listado

añadirá la salida de ls al final de listado.

7.4 Uso de tuberías (pipes)

Ya hemos visto como usar sort como un filtro, pero estos ejemplos suponen que tenemos los datos en un archivo o que los introducimos manualmente por la entrada estándar.

¿Qué pasa si los datos que queremos ordenar provienen de la salida de otro comando, como ls? Por ejemplo, si el contenido de nuestro directorio actual fuese:

/home/diego/articulos$ ls

historia

ingles

notas

tesis

/home/diego/articulos$

Usando la opción “-r” con sort ordenaremos los datos en orden inverso. Una forma de hacer esto sería:

/home/diego/articulos$ ls > listado

/home/diego/articulos$ sort -r listado

tesis

notas

ingles

historia

/home/diego/articulos$

Aquí, escribimos la salida de ls en un archivo y luego ejecutamos “sort -r” sobre él. Pero de esta forma hemos creado un archivo solamente para que los datos generados por ls luego puedan ser leídos por sort. No parece tener demasiado sentido hacer esto.

La solución a este problema es usar los “pipes” (o “tuberías”). Los pipes son una poderosa herramienta provista por el sistema para conectar dos procesos, de manera que la stdout del primero es enviada directamente a la stdin del segundo (esto puede generalizarse para formar una cadena de procesos). Para crear un pipe se usa el símbolo “|”. En nuestro ejemplo, queremos conectar la salida de ls con la entrada de sort:

/home/diego/articulos$ ls | sort -r

tesis

notas

ingles

historia

/home/diego/articulos$

Esta forma es más corta, más eficiente y hasta más fácil de escribir.

Veamos otro ejemplo útil. Al usar el comando:

/home/diego/articulos$ ls /usr/bin

se mostrará una lista de archivos demasiado extensa, parte de la cual pasará rápidamente por la pantalla ante nuestros ojos, sin que podamos leerla. En lugar de esto, usemos less para detener el listado cada vez que se complete la pantalla:

Recordemos que para salir de less hay que presionar [Q].

/home/diego/articulos$ ls /usr/bin | less

Ahora podemos ir avanzando o retrocediendo línea por línea o pantalla por pantalla, cómodamente.

Como dijimos anteriormente, podemos “entubar” más de dos procesos a la vez. head es un filtro que muestra las primeras líneas de la entrada. Si queremos ver el último archivo del directorio actual en orden alfabético, usaremos:

/home/diego/articulos$ ls | sort -r | head -1

tesis

/home/diego/articulos$

Donde “head -1” muestra la primera línea de la entrada que recibe (en este caso, el flujo de datos ordenados inversamente, proveniente de “sort -r”, que es el listado que éste recibió de “ls”).


Página siguiente Página anterior Índice general