4. Tuberías “anónimas” y tuberías nombradas

Volvamos al ejemplo de las tuberías, ya que es sumamente interesante además de ser una buena ilustración de la noción de vínculos. Cuando usa una tubería en una línea de comandos, el shell crea la tubería por Usted y la opera de tal manera que el comando que se encuentra delante de la misma escribe en ella, mientras que el comando que se encuentra detrás de la misma lee de ella. Todas las tuberías, ya sean anónimas (como las que usa el shell) o nombradas (ver abajo), funcionan según el principio FIFO (First In, First Out, Primero en Llegar, Primero en Salir). Ya hemos visto ejemplos de como usar las tuberías en el shell, pero tomemos uno en pos de nuestra demostración:

$ ls -d /proc/[0-9] | head -5
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/

Una cosa que no notará en este ejemplo (porque ocurre muy rápido para que uno lo pueda ver) es que las escrituras en las tuberías son bloqueantes. Esto significa que cuando el comando ls escribe en la tubería, está bloqueado hasta que un proceso del otro lado lea sobre la misma. Para poder visualizar el efecto, puede crear tuberías nombradas, que al contrario de las usadas por el shell, tienen nombres (es decir, están vinculadas, mientras que las del shell no lo están)[7]. El comando para crear dichas tuberías es mkfifo:

$ mkfifo un_tubo
$ ls -il
total 0
169 prw-rw-r--    1 reina     reina            0 sep 10 14:12 un_tubo|
  #
  # Ud. puede ver que el contador de vínculos es 1, y que la salida muestra
  # que el archivo es una tubería ('p')
  #
  # Aquí también puede usar ln:
  #
$ ln un_tubo el_mismo_tubo
$ ls -il
total 0
169 prw-rw-r--    2 reina     reina            0 sep 10 15:37 un_tubo|
169 prw-rw-r--    2 reina     reina            0 sep 10 15:37 el_mismo_tubo|
$ ls -d /proc/[0-9] >un_tubo
  #
  # El proceso está bloqueado, ya que no hay quien lea en el otro extremo.
  # Teclee C-z para suspender el proceso...
  #
[1]+  Stopped                 ls -d /proc/[0-9] >un_tubo
  #
  # ...Luego póngalo en 2do. plano:
  #
$ bg
[1]+ ls -d /proc/[0-9] >un_tubo&
  #
  # ahora lea del tubo...
  #
$ head -5 <el_mismo_tubo
  #
  # ...el proceso que escribe termina
  #
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1]+  Done                    ls -d /proc/[0-9] >un_tubo

$

Similarmente, también las lecturas son bloqueantes. Si ejecutamos los comandos anteriores en orden inverso, observaremos que head se bloquea, esperando que algún proceso le de algo para leer:

$ head -5 <un_tubo
#
# El programa se bloquea, suspenderlo: C-z
#
[1]+  Stopped                 head -5 <un_tubo
#
# Ponerlo en segundo plano...
#
$bg
[1]+  head -5 <un_tubo&
#
# ...Y darle algo de comer :)
#
$ ls -d /proc/[0-9] >el_mismo_tubo
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1]+  Done                    head -5 <un_tubo
$

En el ejemplo previo también se puede ver un efecto no deseado: el comando ls terminó antes que el comando head tomara el relevo. La consecuencia es que Usted volvió al prompt inmediatamente, pero head sólo se ejecutará después. Por lo tanto sólo efectuó su salida después que Usted volvió al prompt.



[7] Existen otras diferencias entre los dos tipos de tuberías, pero las mismas están fuera del alcance de este libro.