% Linux Installation and Getting Started    -*- TeX -*-
% plumbing.tex
% Copyright (c) 1992, 1993 by Matt Welsh, Larry Greenfield and Karl Fogel
%
% This file is freely redistributable, but you must preserve this copyright 
% notice on all copies, and it must be distributed only as part of "Linux 
% Installation and Getting Started". This file's use is covered by
% the copyright for the entire document, in the file "copyright.tex".

% Traduccion realizada por Eduardo Lluna Gil. Envie sus comentarios a:
%            Eduardo Lluna Gil, 2:346/207.8 (FidoNet)
%            elluna@aii.upv.es (InterNet)
% $Log: plumbing.tex,v $
% Revision 0.5.0.1  1996/02/10 23:45:15  rcamus
% Primera beta publica
%
%

\section{Fontaner\'{\i}a UNIX} 
\label{sec-plumbing}

\subsection{Entrada y salida estandard}
\index{entrada estandard|(}
\index{salida estandard|(}
\index{stdin}
\index{stdout}

Muchos comandos UNIX toman su entrada de algo conocido como 
{\bf entrada estandard} y env\'{\i}an su salida a la {\bf salida est\'andar} (a
menudo abreviado como ``stdin'' y ``stdout''). \glossary{stdin}
\glossary{stdout} El int\'erprete de comandos configura el sistema de 
forma que la entrada est\'andar es el teclado y la salida la pantalla.

Veamos un ejemplo con el comando {\tt cat}. Normalmente {\tt cat} lee datos
de los ficheros cuyos nombres se pasan como argumentos en la l\'{\i}nea de
comandos y env\'{\i}a estos datos directamente a la salida est\'andar. Luego, 
usando el comando
\begin{tscreen}
/home/larry/papers\# {\em cat history-final masters-thesis}
\end{tscreen}
mostrar\'a por pantalla el contenido del fichero {\tt history-final} seguido
por {\tt masters-thesis}.

Si no se le pasan nombres de ficheros a {\tt cat} como par\'ametros, leer\'a
datos de stdin y los enviar\'a a stdout. Veamos un ejemplo.
\begin{tscreen}
/home/larry/papers\# {\em cat} \\
{\em Hello there.} \\
Hello there. \\
{\em Bye.} \\
Bye. \\
\key{ctrl-D} \\
/home/larry/papers\# 
\end{tscreen}
\index{se\~nal fin-de-texto}
\index{Se\~nal EOT (end of text,fin de texto)}

Como se puede ver, cada l\'{\i}nea que el usuario teclea (impresa en 
it\'alica) es inmediatamente reenviada al monitor por {\tt cat}. Cuando 
se est\'a leyendo de la entrada est\'andar, los comandos reconocen el fin 
de la entrada de datos cuando reciben el car\'acter EOT (end-of-text, fin 
de texto). Normalmente es generado con la combinaci\'on \key{ctrl-D}.

% By the way, guys, there's no such thing as an EOF character in UNIX. The
% terminal signal to signal EOT (end of text) is usually ^D. Files on
% disk don't have a terminating EOF as MS-DOS files do. The data just
% ends, and the read() call signals the end of data. :) --mdw

Veamos otro ejemplo. El comando {\tt sort} toma como entrada l\'{\i}neas de 
texto (de nuevo leer\'a desde stdin si no se le proporcionan nombres de 
ficheros en la l\'{\i}nea de comandos), y devuelve la salida ordenada a 
stdout. Pruebe lo siguiente:
\begin{tscreen}
/home/larry/papers\# {\em sort} \\
{\em bananas} \\
{\em carrots} \\
{\em apples} \\
\key{ctrl-D} \\
apples \\
bananas \\
carrots \\
/home/larry/papers\# 
\end{tscreen}

Podemos ordenar alfab\'eticamente la lista de la compra... ?`no es \'util 
UNIX?

\subsection{Redireccionando la entrada y salida}
\index{redirecci\'on!entrada est\'andar}
\index{redirecci\'on!salida est\'andar}
\index{salida!redirecci\'on}
\index{salida est\'andar!redirecci\'on}
% \index{>@{\tt >}}

Ahora, supongamos que queremos que la salida de {\tt sort} vaya a un 
fichero para poder salvar la lista ordenada de salida. El int\'erprete de 
comandos nos permite {\bf redireccionar} la salida est\'andar a un fichero 
%usando el s\'{\i}mbolo ``{\tt >}''. Veamos como funciona.
usando el s\'{\i}mbolo ``{\tt >}''. Veamos como funciona.

\begin{tscreen}
/home/larry/papers\# {\em sort $>$ shopping-list} \\
{\em bananas} \\
{\em carrots} \\
{\em apples} \\
\key{ctrl-D} \\
/home/larry/papers\# 
\end{tscreen}

Como puede ver, el resultado de {\tt sort} no se muestra por pantalla, en
su lugar es salvado en el fichero {\tt shopping-list}.
Echemos un vistazo al fichero.
\begin{tscreen}
/home/larry/papers\# {\em cat shopping-list} \\
apples \\
bananas \\
carrots \\
/home/larry/papers\# 
\end{tscreen}
Ya podemos ordenar la lista de la compra y adem\'as guardarla.

Supongamos ahora que ten\'{\i}amos guardada nuestra lista de compra 
desordenada original en el fichero {\tt items}. Una forma de ordenar la 
informaci\'on y salvarla en un fichero podr\'{\i}a ser darle a {\tt sort} el 
nombre del fichero a leer en lugar de la entrada est\'andar y 
redireccionar la salida est\'andar como hicimos arriba.
\begin{tscreen}
/home/larry/papers\# {\em sort items $>$ shopping-list} \\
/home/larry/papers\# {\em cat shopping-list} \\
apples \\
bananas \\
carrots \\
/home/larry/papers\# 
\end{tscreen}
\index{entrada!redirecci\'on}
\index{entrada est\'andar!redirecci\'on}
\index{<@{\tt <}}
Hay otra forma de hacer esto. No solo puede ser redireccionada la salida
est\'andar, tambi\'en puede ser redireccionada la {\em entrada\/} est\'andar
usando el s\'{\i}mbolo ``{\tt <}''.
\begin{tscreen}
/home/larry/papers\# {\em sort $<$ items} \\
apples \\
bananas \\
carrots\\
/home/larry/papers\# 
\end{tscreen}
T\'ecnicamente, {\tt sort < items} es equivalente a {\tt sort items}, pero nos
permite demostrar que {\tt sort < items} se comporta como si los datos del
fichero fueran tecleados por la entrada est\'andar. El int\'erprete de comandos
es quien maneja las redirecciones. {\tt sort} no recibe el nombre del
fichero ({\tt items}) a leer, desde el punto de vista de {\tt sort}, est\'a
leyendo datos de la entrada est\'andar como si fueran tecleados desde el
teclado.

\index{filtros!definici\'on}
Esto introduce el concepto de {\bf filtro}. Un filtro es un programa que lee
datos de la entrada est\'andar, los procesa de alguna forma, y devuelve los
datos procesados por la salida est\'andar. Usando la redirecci\'on la entrada
est\'andar y/o salida est\'andar pueden ser referenciadas desde ficheros.
{\tt sort} es un filtro simple: ordena los datos de entrada y env\'{\i}a el
resultado a la salida est\'andar. {\tt cat} es incluso m\'as simple, no hace
nada con los datos de entrada, simplemente env\'{\i}a a la salida cualquier 
cosa que le llega.

\subsection{Uso de tuber\'{\i}as (pipes)}\glossary{pipe}

\index{pipes!uso de|(}
\index{tuber\'{\i}as!uso de|(}

Ya hemos visto como usar {\tt sort} como un filtro. Pero estos ejemplos
suponen que tenemos los datos en un fichero en alguna parte o vamos a
introducir los datos manualmente por la entrada est\'andar. ?`Qu\'e pasa 
si los datos que queremos ordenar provienen de la salida de otro comando, 
como {\tt ls}?. Por ejemplo, usando la opci\'on {\tt -r} con {\tt sort} 
ordenaremos los datos en orden inverso. Si queremos listar los ficheros 
en el directorio actual en orden inverso, una forma podr\'{\i}a ser.

\begin{tscreen}
/home/larry/papers\# {\em ls} \\
english-list \\
history-final \\
masters-thesis \\
notes \\
/home/larry/papers\# {\em ls $>$ file-list} \\
/home/larry/papers\# {\em sort -r file-list} \\
notes \\
masters-thesis \\
history-final \\
english-list \\
/home/larry/papers\# 
\end{tscreen}
Aqu\'{\i}, salvamos la salida de {\tt ls} en un fichero, y entonces ejecutamos
{\tt sort -r} sobre ese fichero. Pero esta forma necesita crear un fichero
temporal en el que salvar los datos generados por {\tt ls}.

\index{pipes!definici\'on}
\index{pipes!creaci\'on}
\index{tuber\'{\i}as!definici\'on}
\index{tuber\'{\i}as!creaci\'on}

La soluci\'on es usar las {\bf pipes}\NT{tuber\'{\i}as}. El uso de pipes 
es otra caracter\'{\i}stica del int\'erprete de comandos, que nos permite 
conectar una cadena de comandos en un ``pipe'', donde la stdout del primero 
es enviada directamente a la stdin del segundo y as\'{\i} sucesivamente.
Queremos conectar la salida de {\tt ls} con la entrada de {\tt sort}.
Para crear un pipe se usa el s\'{\i}mbolo ``{\tt |}'':
\begin{tscreen} 
/home/larry/papers\# {\em ls $\mid$ sort -r} \\
notes \\
masters-thesis \\
history-final \\
english-list \\
/home/larry/papers\# 
\end{tscreen}
Esta forma es m\'as corta y obviamente m\'as f\'acil de escribir.

Otro ejemplo \'util--- usando el comando
\begin{tscreen}
/home/larry/papers\# {\em ls /usr/bin} 
\end{tscreen}
mostrar\'a una lista larga de los ficheros, la mayor\'{\i}a de los cuales 
pasar\'a r\'apidamente ante nuestros ojos sin que podamos leerla. En 
lugar de esto, usemos {\tt more} para mostrar la lista de ficheros en 
{\tt /usr/bin}. 
\begin{tscreen}
/home/larry/papers\# {\em ls /usr/bin $\mid$ more} 
\end{tscreen}
Ahora podemos ir avanzando p\'agina a p\'agina comodamente.

!`Pero la diversi\'on no termina aqu\'{\i}!. Podemos ``entubar'' m\'as de 
dos comandos a la vez. El comando {\tt head} es un filtro que muestra la 
primeras l\'{\i}neas del canal de entrada (aqu\'{\i} la entrada desde una 
pipe). Si queremos ver el \'ultimo fichero del directorio actual en orden 
alfab\'etico, usaremos: 
\begin{tscreen}
/home/larry/papers\# {\em ls $\mid$ sort -r $\mid$ head -1} \\
notes \\
/home/larry/papers\# 
\end{tscreen}
Donde {\tt head -1} simplemente muestra la primera l\'{\i}nea de la 
entrada que recibe {en este caso, el flujo de datos ordenados 
inversamente provenientes de {\tt ls}).
\index{pipes!uso de|)}
\index{tuber\'{\i}as!uso de|)}

\subsection{Redirecci\'on no destructiva}
\index{ficheros!a\~nadir a}
\index{redirecci\'on!no destructiva}

El uso de ``{\tt >}'' para redireccionar la salida a un fichero es destructivo:
en otras palabras, el comando
\begin{tscreen}
/home/larry/papers\# {\em ls $>$ file-list}
\end{tscreen}
sobreescribe el contenido del fichero {\tt file-list}. Si en su lugar,
usamos el s\'{\i}mbolo ``{\tt >>}'', la salida ser\'a a\~nadida al final del fichero 
nombrado, en lugar de ser sobreescrito.
\begin{tscreen}
/home/larry/papers\# {\em ls $>>$ file-list}
\end{tscreen}
a\~nadir\'a la salida de {\tt ls} al final de {\tt file-list}.

Es conveniente tener en cuenta que la redirecci\'on y el uso de pipes son
caracter\'{\i}sticas proporcionadas por el int\'erprete de comandos--- este,
proporciona estos servicios mediante el uso de la sintaxis ``{\tt >}'', 
``{\tt >>}'' y ``{\tt |}''. 

\index{entrada est\'andar|)}
\index{salida est\'andar|)}
% Need to cover use of << and possibly use of stderr. Problem with 
% covering stderr is that it's different in different shells. Maybe later.

