2.8.- Tuberías de comunicación

Una tubería (pipe en inglés) permite la comunicación entre dos procesos. La tubería se representa con una barra vertical «|«.

Pulsando estas tres teclas a la vez obtenemos el símbolo pipe «|».

La sintaxis general para «conectar» 2 o mas comandos es:

El carácter pipe ( | ) conecta la salida estándar del comando1 a la entrada estándar de el
comando2 y así sucesivamente. Los comandos pueden ser tan simples o complejos como
sea requerido.

Veamos un ejemplo:

Las figuras de abajo representa el mecanismo asociado a la tubería de comunicación.

Mecanismo interno de la tubería de comunicación. Primera etapa.

En esta primera etapa se ha establecido la tubería entre los 2 Shells.

Mecanismo interno de la tubería de comunicación. Segunda etapa.

En la segunda etapa cada shell se reemplaza con su comando.

Sean cuales sean los comandos presentes a cada lado de la tubería, el shell de trabajo detecta el carácter | en la línea de comandos y creará un Shell hijo (1) que, a su vez, hace lo mismo (2).

El primer shell hijo (PID=205) disocia su salida estándar del terminal y la conecta a la entrada estándar de la tubería (3).

El segundo shell hijo (PID=206) disocia su entrada estándar del terminal y la conecta a la salida de la tubería (4).

Aquí termina el trabajo del los Shell’s hijo, entonces, cada uno de los Shell hijo se reemplaza con su comando (5a y 5b).

Cada comando empieza ahora a ejecutarse. Cuando el comando who escribe en su salida estándar, los mensajes van dentro de la tubería (6a).

Paralelamente, el comando mail lee su entrada estándar (6b), lo que provoca la extracción de los datos contenidos en la tubería.

Un pipe puede ser creado entre cualquier par de programas, siempre y cuando el primer programa envié su salida a la salida estándar (stdout) y el segundo programa lea su entrada de datos de la entrada estándar (stdin). La salida de error estándar del comando de la izquierda no va a la tubería.

Como otro ejemplo, supongamos que se desea saber el numero de archivos existentes en el directorio. Sabiendo que el comando ls despliega una linea por cada archivo existente y wc cuenta el número de líneas podríamos utilizar la misma técnica que en el ejemplo anterior:

 Comandos que no leen su entrada estándar

Hay una serie de comandos en Linux/Unix que no interesa ponerlos detrás de una tubería, ya que no realizan lecturas en su entrada estándar. Por ejemplo:

  • ls
  • who
  • find
  • chmod
  • cp
  • mv
  • rm
  • ln
  • mkdir
  • rmdir
  • date
  • kill
  • file
  • type
  • echo

y algunos más (que omito para no extendernos)

Comandos que leen su entrada estándar

Los comandos que leen su entrada estándar son fácilmente identificables puesto que requieren una entrada de datos por el teclado. Por ejemplo:

Estos dos comandos pueden colocarse detrás de una tubería:

Filtros.- Primer modo

El comando recibe al menos un nombre de archivo como argumento.

Aquí, este comando no lee su entrada estándar. No tiene ninguna necesidad de hacerlo. porque ha recibido un nombre de archivo como argumento, por lo que es éste último el que se va a tratar.

Ejemplo 1:

Poner esto comando detrás de una tubería no es imposible pero carece de utilidad, ya que el comando no extraerá nunca los datos contenidos en ella.

Ejemplo 2

El comando who escribe en la tubería. Por lo tanto, su resultado no aparecerá por pantalla.Por contra al comando wc no le importa su entrada estándar (porque recibe un archivo como parámetro), y por extensión, el contenido de la tubería. Abre el archivo /etc/passwd en modo lectura, cuenta el número de líneas del archivo y muestra el resultado por su salida estándar.

Filtros.- Segundo modo

El comando no recibe ningún nombre de archivo como argumento. En este caso, el comando tratará los datos que le lleguen por su entrada estándar.

Ejemplo

Por lo tanto es posible colocar este comando detrás de una tubería:

Averiguar si su comando lee su entrada estándar

Tenemos dos métodos que permiten saber si un comando lee su entrada estándar (la información está en el manual del comando).

Ejemplo

 Veamos a continuación una parte del manual del comando wc. Constatamos que argumento [file …] es opcional, lo que se convierte en una primera señal.

Explicación del argumento file.

Si el nombre del archivo se omite, el comando lee su entrada estándar.

Otra posibilidad consiste en probar el comando sin dar ningún nombre de archivo como argumento.

Ejemplo 1

Vamos a probar a continuación un comando que trata un archivo. No desencadena una lectura de la entrada estándar:

Por lo que es inútil colocar este comando detrás de una tubería.

A continuación el mismo comando sin el nombre del archivo. El comando espera una entrada de datos por el teclado:

Por lo tanto este comando puede colocarse detrás de una tubería:

Ejemplo 2

Ahora mostramos otro comando que trata un archivo. No desencadena una lectura de la entrada estándar:

El mismo comando sin el nombre del archivo genera un mensaje de error. Por lo tanto, el nombre del archivo es obligatorio:

Si lo colocamos detrás de una tubería, mostrará el mismo mensaje de error. Por lo tanto es inútil insistir, este comando no lee su entrada estándar:

Caso particular de ciertos comandos

A la mayoría de comandos no les importa si están situados detrás de una tubería o no: Para un comando determinado, la acción será siempre la misma:

Ejemplo

wc -l – Lee su entrada estándar en los dos casos.

Algunos comandos son la excepción de la regla. Verifican si su entrada estándar está conectada a la salida de una tubería o a un terminal. Éste es el caso del comando more:

Ejemplos

El comando more recibe un archivo como argumento y pagina su contenido por pantalla. No lee su entrada estándar:

Sin el nombre del archivo, el comando muestra un mensaje de error (el argumento [filename] es por lo tanto opcional). Aquí more no lee su entrada estándar:

 Podemos omitir el nombre del archivo cuando more se coloca a la derecha de una tubería. En este caso, lee su entrada estándar y pagina las líneas que extrae:

Complementos

Encadenar tuberías

podemos encadenar múltiples tuberías en una línea de comandos.

Ejemplo

Vamos a mostrar el número de conexiones del usuario atika:

 Duplicar las salidas

El comando tee permite visualizar un resultado por pantalla y guardarlo a la vez en un archivo.

Ejemplos

El comando tee muestra por su salida estándar las líneas extraídas de la tubería y las escribe en el archivo listado_archivo. Si listado_archivo ya existe, este se sobre escribe:

 El resultado del comando date se muestra por pantalla y concatenado (unido) con el archivo listado_archivo existente:

Enviar la salida estándar y la salida de error estándar por la tubería

Ejemplo

El siguiente comando muestra un mensaje de error y una línea de resultado:

Solamente la salda estándar llega a la tubería:

Si usamos la duplicación del descriptor , la salida 2 se redirige a la salida 1 (terminal):