\section{Redirección de entradas y salidas}
\label{sec:redireccion}

\subsection{Entrada, salida y error estándar}
Haremos una breve introducción a los conceptos que definen los
componentes de un programa en línea de comandos.

Una traducción no oficial de

\begin{verbatim}
$ info "Text utilities" "Opening the software toolbox" "Toolbox introduction"
\end{verbatim}
%$


<<Mucha gente lleva una navaja de la Armada Suiza en los bolsillos de
sus pantalones (o cartera). Una navaja de la Armada Suiza es una
herramienta útil de tener: tiene varias hojas de cuchillo, un
destornillador, pinzas, palillo para dientes, 
%(nail file)?
sacacorchos y probablemente unas cuantas cosas más. Para trabajos
pequeños misceláneos de todos los días donde se necesita una herramienta
de propósito general, es la herramienta indicada.

Por otro lado, un carpintero experimentado no construye una casa
utilizando una navaja de la Armada Suiza. En cambio, posee una caja
de herramientas llena de herramientas especializadas--una sierra, un
martillo, un destornillador, 
%a plane
etc. Y conoce exactamente  dónde y cuando utilizar cada herramienta; no
le vas a coger martilleando clavos con el mango del destornillador.>>

La filosofía de Unix (en línea de comandos) cree que un único programa
\emph{especializado} para hacer todas las tareas no es bueno, al menos
no para usuarios avanzados o administradores.

Los usuarios finales sin conocimientos en áreas informáticas pueden
preferir tener un sólo programa para todo, pero este único programa
tiene dificultades para el mantenimiento y modificación. Se vuelve
monstruoso y complicado.

En reemplazo se prefiere la \emph{navaja de la Armada Suiza} para
tareas cotidianas, o sea, un conjunto de programas pequeños de gran
simplicidad que en conjunto se potencian.

Para que los programas trabajen en conjunto se utiliza el concepto de
\textbf{\emph{flujo}} como una corriente de bytes.

Al igual que con las tuberías reales (digamos caños, los grifos o
canillas, duchas, etc.)  de una casa, se conectan unos a otros donde
cada uno tiene una \emph{entrada}, una \emph{función} y una
\emph{salida}. El concepto de <<tuberías>> lo veremos en la sección
\ref{subsection:tuberias} por ahora vamos a distinguir los otros tres
aspectos con un ejemplo.

El comando \comando{sort} puede ordenar por orden alfabético. \'{E}sta
sería la \emph{función} del programa. Pero ?`qué ordena? bueno aquí es
donde interviene la \emph{entrada}. Que sin utilizar la magia de las tuberías,
será el \textbf{teclado} la entrada.

Haremos una prueba:

\begin{verbatim}
$ sort
El 
comando 
sort 
puede
ordenar 
por
orden
alfabético
\end{verbatim}
%$
... luego presionamos Ctrl-D que significa ``fin de archivo'' en la mayoría de
los casos, apareciendo en pantalla:

\begin{verbatim}
alfabético
comando
El
orden
ordenar
por
puede
sort
\end{verbatim}

Con este ejemplo nos damos cuenta que la \emph{salida} es la \textbf{pantalla}

A estas alturas un opodría preguntarse ``Pero no es la única
entrada que posee mi programa''; es verdad que un programa puede tener
muchas entradas y muchas salidas. Por ejemplo cuando lee un archivo,
éste es una entrada más. Pero los conceptos que venimos estudiando son
entradas y salidas especiales, llamadas \emph{entrada estándar} y
\emph{salida estándar}.

También existe un tipo de salida adicional que es el \emph{error estándar}. 
Por este flujo se canalizan todos los mensajes de error o avisos del programa.
Facilitando varias tareas. Una muy común es reunir todos los errores en un
archivo separado en caso de problemas, para su posterior análisis.

En nuestro ejemplo si \comando{sort} intentaba abrir un archivo y no existía,
es preferible que escriba:

\begin{verbatim}
Fichero o directorio no existe
\end{verbatim}

Antes de que lo canalice como salida estándar y diga

\begin{verbatim}
directorio
existe
Fichero
no
o
\end{verbatim}

Teniendo claro los conceptos vamos a ver cómo utilizamos las
tuberías para <<unir>> los programas entre sí.

\subsection{Tuberías (pipes)}
\label{subsection: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
\ref{fig:Shell-RedireccionIO-Diagrama-Sort} siendo la entrada estándar
el teclado y la salida estándar <<el terminal>> o por simplicidad la
pantalla.

\figura{Esquema de entrada y salida estándar del
  ejemplo}{Shell-RedireccionIO-Diagrama-Sort}

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
\comando{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 \ref{fig:Shell-RedireccionIO-Diagrama-Diccionario}.
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>>. 

\figura{Esquema de entrada y salida estándar del
  ejemplo 2}{Shell-RedireccionIO-Diagrama-Diccionario}

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:

\begin{verbatim}
$ sort | dicccionario
\end{verbatim}
%$

Donde el caracter \comando{|} 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 \comando{sacar-repetidas}, la línea de comando sería:

\begin{verbatim}
$ sort | sacar-repetidas | diccionario
\end{verbatim}
%$

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
salida estándar un archivo, así se procesa como la entrada estándar
del \comando{sort} y continúa el proceso normalmente. Este comando es
\comando{cat}. La sintaxis es simple {\tt cat
  \emph{nombre-de-archivo}}.

Quedando nuestro ejemplo:

\begin{verbatim}
$ cat archivo.txt | sort | sacar-repetidas | diccionario
\end{verbatim}
%$

... crea un glosario de las palabras que se encuentren en \archivo{archivo.txt}

La combinación de comandos es incalculable y brinda posibilidades
enormes. Veremos algunos ejemplos en los ejercicios.

\subsection{Redirección}

Si bien  nuestro ejemplo es ilustrativo, es bueno ver los resultados
en pantalla. En repetidas ocaciones en la vida de un sistema es mejor tener
todo en archivos, ya sea para guardar historial de algo 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
\emph{Redirecciones}.

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

\subsubsection{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, \textbf{no se
  realizan confirmaciones}. Si el archivo a escribir existe y posee
información valiosa, aplicar \comando{> archivo-importante} lo sobreescribe
con el contenido del flujo.

En cambio el operador (>>) realiza un
\emph{agregado}\footnote{\emph{append} en inglés} de los datos en el flujo.

No hay nada mejor que un ejemplo clarificador:

\begin{verbatim}
$ escribe-en-salida-estandar > archivo.txt 
\end{verbatim}
%$

El (falso) comando \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} o cualquier comando antes visto, así como
también una combinación de comandos por tuberías.

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

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

\begin{verbatim}
$ echo Este es el acontecimiento Nro. 1 > bitacora.log
$ echo Este es el segundo acontecimiento >> bitacora.log
\end{verbatim}

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

\textbf{Ejemplo} Si queremos combinar el ejemplo de las tuberías en
la sección \ref{subsection:tuberias} con lo aprendido recientemente
podríamos escribir:

\begin{verbatim}
$ cat archivo.txt | sort | sacar-repetidas | diccionario >> glosario.txt
\end{verbatim}
%$

\subsubsection{Lectura}
 

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

\begin{verbatim}
$ comando-que-acepta-stdin < archivo-de-entrada.txt
\end{verbatim}
%$


%% lo afirmado abajo es una mentira piadosa, es solo que no doy 
%% para entregarlo a tiempo...
Debido a que preferimos el comando \comando{cat} para estas operaciones
por una mayor legibilidad.

%%%%%%%%%%%%
% Práctica %
%%%%%%%%%%%%
\input{Shell/RedireccionIO-practica}