.. include:: ../../my-header_2.txt

Entrada/Salida Estándar
-----------------------

Las ideas de **filtro** y **redirección** son de una sencillez conceptual desconcertante. Puedes imaginarte el filtro como un elemento con dos mangueras flexibles. Por una entra un flujo de información (*stream* en la jerga de UNIX) y por la otra sale otro flujo convenientemente procesado. Las mangueras puedes conectarlas a ficheros (es decir, dispositivos, ficheros ordinarios y otros elementos que ya descubriremos). Siguiendo con la metáfora, si el filtro es una depuradora de agua, por la manguera de entrada entra agua sucia y por la de salida sale agua potable. Puedes imaginar una salida adicional por la que, en caso de mal funcionamiento, saldría aceite, humo o cualquier otro subproducto no relacionado con la función de la depuradora.

¿Cómo se construye un programa que se comporte de acuerdo a ese modelo? En realidad, los primeros programas que construimos utilizando las funciones de la biblioteca estándar de C más sencillas (``getchar``, ``scanf``, ``putchar``, ``printf``) funcionan según este modelo. Estas funciones son así de simples porque no hay que especificar de dónde viene la entrada o a dónde va la salida. En estas funciones se asume que la entrada/salida tiene un origen/destino predeterminado, lo que se denomina **entrada/salida estándar**. 

Los usuarios noveles de Linux piensan que la entrada estándar es el teclado y la salida estándar la pantalla. Esta idea no es correcta, como ya has podido comprobar. En efecto, cuando redireccionas un filtro para que tome la entrada de otro dispositivo (más formalmente, *fichero*), el filtro leerá ahora de ese dispositivo y no del teclado ...¡y su código seguirá siendo el mismo! El dispositivo teclado/pantalla, o terminal, de nombre ``/dev/tty``, suele ser la asignación inicial de la entrada/salida estándar. Esto es lo que observas cuando abres la aplicación *terminal* en Linux.  Pero precisamente, el hecho de ser entrada/salida estándar significa que esa asignación se puede cambiar mediante la redirección. Y esto es aplicable al propio *shell*, que no es sino un filtro. Ya sabíamos que podemos ejecutar el ``bash`` como cualquier otro programa. Pues bien, ahora ya sabes que puedes hacer::

    bash < entrada > salida

donde ``entrada`` es un fichero de texto donde previamente has metido órdenes. Y no es necesario que sea ejecutable.

Si buscas en el ``man`` las funciones de entrada/salida estándar encontrarás que estas tienen asociadas respectivas compañeras (por ejempo, ``getc`` para ``getchar``) caracterizadas por un argumento extra. Como verás, ese argumento no indica un nombre de fichero o dispositivo, sino lo que se conoce como **descriptor de fichero**, *file descriptor*. Un descriptor de fichero es un *nombre lógico* con el que el programa se refiere a un fichero. En algún momento, el sistema operativo o un programa, tal vez el *shell*, asocian al descriptor de fichero un fichero (o dispositivo, ya que siempre me estoy refiriendo a la abstracción). Dejaremos para más adelante cómo se hace esa asociación. De momento sabemos que podemos describir la entrada/salida estándar en términos de descriptores de fichero. 

Una operación de entrada/salida estándar no requiere especificar un descriptor de fichero, por ejemplo ``getchar()``. Pero, ¿existen descriptores de ficheros explícitos, por ejemplo para usar en funciones de biblioteca de C como ``getc()``, para la entrada/salida estándar? La respuesta es afirmativa:

* ``stdin`` es el descriptor de fichero para la entrada estándar.
* ``stdout`` es el descriptor de fichero para la salida estándar.
* ``stderr`` es el descriptor de fichero para la salida estándar de error.


  .. image:: ../../_static/Figuras/Mangueras.jpg
       :width: 600 px


.. include:: ../../my-footer_2.txt






