%***********************************************************************
%
%       Spanish Translation by:  César Ballardini,
%                                cballard@santafe.com.ar
%                                May 9, 1997
%
%***********************************************************************
\chapter{El shell de \unix}\label{shell-chapter}

\begin{fortune}
  \raggedright Es muy fácil crear archivos en el sistema operativo
  UNIX.  Por lo tanto, los usuarios tienden a crear muchos archivos
  que utilizan una gran cantidad de espacio.  Se ha dicho que la única
  cosa estándar y común a todos los sistemas UNIX es el
  mensaje-del-día que les pide a los usuarios que borren los
  archivos que no necesitan.\\
  \raggedleft Guía del administrador de System V.2
\end{fortune}

\section{Comandos \unix}

Cuando ingresa al sistema \unix, se enfrenta con algo más o menos como
lo que se muestra a continuación:

\begin{screen}
\begin{verbatim}
/home/larry$
\end{verbatim}
\end{screen}
% $

Ese ``algo'' se denomina \concept{prompt}\footnote{N. del T.: {\em
    prompt\/} significa {\em solicitud}.}.  Como su nombre sugiere, le
solicita a Ud. que ingrese un comando.  Todos los comandos \unix\ 
consisten de una secuencia de letras, números y
caracteres\glossary{caracteres}.  No son válidos los espacios dentro
del nombre del comando.  Algunos comandos válidos son \cmdnm{mail},
\cmdnm{cat}, y \cmdnm{CMU\_is\_Number-5}.  Algunos caracteres no están
permitidos---volveremos a este tema más adelante.  \unix\ además hace
\concept{diferencia entre mayúsculas y minúsculas}\footnote{La
  diferenciación entre mayúsculas y minúsculas es una cosa muy
  personal.  Algunos sistemas operativos como OS/2\index{OS/2} y
  Windows NT\index{Windows NT} preservan las diferencias, pero no las
  cuentan como distintas.  En la práctica habitual con \unix, se
  utiliza raramente la diferenciación.  La situación de tener un par
  de comandos \cmdnm{Cat} y \cmdnm{cat} diferentes, no es común.}, lo
que significa que \cmdnm{Cat} y \cmdnm{cat} son comandos distintos.

El prompt se muestra como resultado del accionar de un programa
especial denominado \concept{intérprete de comandos}\index{intérprete
  de comandos}\footnote{N. del T.: {\em intérprete de comandos\/} del
  inglés {\em shell}.}.  El intérprete de comandos o shell acepta los
comandos que escribe el usuario y los ejecuta.  Los comandos pueden
formar programas en el lenguaje del intérprete de comandos, y a dichos
programas se los denomina ``guiones de shell''\index{intérprete de
  comandos!programación}\index{intérprete de
  comandos!guión}\index{shell!script}.

Los shell en \unix\ se clasifican en dos grandes grupos: los tipo
Bourne y los tipo C.  Los shell tipo Bourne toman su nombre a partir
de su inventor, Steven Bourne\index{Bourne, Steve R.}.  Steven Bourne
escribió el shell original de \unix, denominado
\cmdnm{sh}\ttindex{sh}; a partir de entonces, la mayoría de los shells
tienen un nombre con el sufijo \cmdnm{sh} para indicar que son
extensiones de la idea original.  Existen varias implementaciones de
este shell, que colectivamente llevan el nombre de shells Bourne.
También son comunes los shells tipo C cuyo original fue implementado
por Bill Joy\index{Joy, Bill}.  Tradicionalmente, los shell Bourne se
han utilizado para los scripts de shell y por razones de
compatibilidad con el \cmdnm{sh} original, mientras que los shells C
han sido más comunes en su aplicación interactiva.  (Los C tienen
ventajas en cuanto a sus mejores características interactivas, aunque
son más difíciles de programar.)

\linux\ viene con un shell Bourne denominado
\cmdnm{bash}\ttindex{bash}, escrito por la organización ``Free
Software Foundation''\footnote{N. del T.: La Fundación para el
  Software Libre ---tal es la traducción de su nombre--- se ocupa de
  la producción y distribución de software que no tiene limitaciones
  en su uso y/o copia, enfrentando de esta manera las prácticas de las
  compañías tradicionales de desarrollo.  Que el software sea libre no
  significa que sea barato: la libertad incluye la gratuidad, pero es
  mucho más que ello.}.  El nombre \cmdnm{bash} proviene de {\bf
  B}ourne {\bf A}gain {\bf SH}ell, uno de los tantos juegos de
palabras en \unix.  Se trata de un shell Bourne ``avanzado'': tiene
las capacidades estándar de programación que se encuentran en todos
los shells Bourne y además varias de las características interactivas
que se encuentran en los shells C.  \cmdnm{bash} es el shell
predeterminado cuando uno usa \linux.

Apenas ingresa por primera vez, el prompt que Ud. ve es producto de la
acción de \cmdnm{bash}, en otras palabras: está Ud. corriendo su
primer programa \unix, el shell \cmdnm{bash}.  Mientras esté
conectado, el shell \cmdnm{bash} estará permanentemente funcionando.

\subsection{Un comando \unix\ típico}

El primer comando que debe conocer es \cmdnm{cat}\ttindex{cat}.  Para
utilizarlo, escriba \cmdln{cat} y luego oprima \ret:

\begin{screen}\begin{verbatim}
/home/larry$ cat

\end{verbatim}\end{screen}
% $
    
Si tiene ahora el cursor posicionado en una línea nueva, entonces lo
que ha hecho está bien.  Existen unas cuantas variantes que podría
haber tecleado---algunas funcionarán, otras no.

\begin{itemize}
\item Si tuvo algún error de tecleo al escribir \cmdln{cat}, debería
  haber visto algo más o menos así:
\begin{screen}\begin{verbatim}
/home/larry$ ct
ct: command not found
/home/larry$
\end{verbatim}\end{screen}
    Por lo tanto, el shell le informa que no pudo encontrar un
    programa denominado \cmdln{ct}, y le ofrece otro prompt para
    seguir trabajando.  Recuerde que \unix\ hace diferencia entre
    mayúsculas y minúsculas: \cmdnm{CAT} está mal escrito.
  \item Puede que Ud. haya escrito algunos espacios en blanco antes
    del comando, como:\footnote{El `{\tt \char `\ }'\ indica que el
      usuario escribió un espacio.}
\begin{screen}\begin{verbatim*}
/home/larry$     cat     
\end{verbatim*}\end{screen}% $
    
    Sin embargo, el resultado es correcto, y el programa \cmdnm{cat}
    corre sin problemas.
% any more ideas for common things?
  \item También puede que haya oprimido un \ret\ en una línea en
    blanco; no se preocupe y continúe, pues no tiene ningún efecto.
\end{itemize}

Doy por sentado que Ud. ha corrido con éxito \cmdnm{cat}\ttindex{cat}
y está esperando que haga algo que lo maraville.  Pues bien, no, no es
un juego.  \cmdnm{cat} es una muy útil utilidad que no parece muy útil
a primera vista.  Escriba cualquier cosa y luego oprima \ret.  Lo que
verá es:

\begin{tscreen}
/home/larry\$ cat\\
{\sl Help! I'm stuck in a Linux program!}\\
Help! I'm stuck in a Linux program!
\end{tscreen}

(El texto {\sl inclinado\/} marca que es lo que he tecleado.)  Lo que
parece haber hecho \cmdnm{cat} es devolver un eco de lo escrito.  Esto
es útil a veces, tal vez no ahora.  Así que salgamos de este programa
y veamos otros con beneficios más obvios.

Para finalizar ciertos comandos \unix, teclee \eof\footnote{Mantenga
  oprimida la tecla etiquetada \key{Ctrl} y aprete \key{d}, luego
  suelte ambas.}.  \eof\ es el carácter end-of-file\footnote{N. del
  T.: fin de archivo.}, o EOF, para abreviar\index{fin de
  archivo}\index{end of file}.  Puede que en ciertos libros de texto
aparezca como end-of-text\footnote{N. del T.: fin de texto.}.  Nos
referiremos a este carácter como EOF.  Es un carácter de control que
informa a los programas \unix\ que ha cesado el ingreso de datos.
Cuando \cmdnm{cat} ve que no teclea más nada, termina.

Para ver otro ejemplo parecido, pruebe el programa
\cmdnm{sort}\ttindex{sort}.  Como su nombre lo indica, \cmdnm{sort} es
un programa de clasificación.  Si Ud.\ teclea unas cuantas líneas y
luego oprime \eof, \cmdnm{sort} las mostrará a la salida de manera
ordenada.  Esta clase de programas se denominan {\bf
  filtros}\glossary{filtro}, porque toman texto desde su entrada, lo
filtran, y lo vierten a su salida modificado de alguna manera.  Tanto
\cmdnm{cat} como \cmdnm{sort} son filtros inusuales.  \cmdnm{cat} es
inusual pues lee el texto de entrada y \emph{no} lo cambia.
\cmdnm{sort} es inusual porque lee \emph{todas} las líneas de entrada
hasta el EOF, antes de emitir su salida.  La mayoría de los filtros
trabajan sobre la base de línea por línea: leen una línea de la
entrada, realizan cierto cómputo, y escriben una línea diferente de
salida.

\section{Autoayuda}\label{man-section}\bindex{help!on-line}

El comando \cmdnm{man}\impttindex{man} muestra las páginas de la guía
de referencia para un comando dado\footnote{\cmdnm{man} también puede
  mostrar información acerca de las llamadas al sistema, subrutinas,
  formatos de archivos, etc..  En la versión original de \unix\ el
  comando mostraba la información exactamente igual a la que aparecía
  en la documentación impresa.  Por ahora, es probable que Ud. sólo
  esté interesado en obtener ayuda acerca de los comandos.}.  Por
ejemplo:

\begin{screen}
\begin{verbatim}
/home/larry$ man cat

cat(1)                                                     cat(1)

NAME
  cat - Concatenates or displays files

SYNOPSIS
  cat [-benstuvAET] [--number] [--number-nonblank] [--squeeze-blank]
  [--show-nonprinting] [--show-ends] [--show-tabs] [--show-all]
  [--help] [--version] [file...]

DESCRIPTION
  This manual page documents the GNU version of cat ...
\end{verbatim}
\end{screen}% $

Hay aproximadamente una página completa de información sobre
\cmdnm{cat}\footnote{N. del T.: El ejemplo se ha mantenido en inglés,
  pues es muy probable que Ud. tenga instaladas las páginas de manual
  en dicho idioma, de manera predeterminada.  Pruebe más tarde de
  instalar el conjunto de páginas de manual que están disponibles en
  castellano.}.  Pruebe correr \cmdln{man} en este momento.  No espere
entender la página de manual que se le muestra.  Las páginas de manual
suponen un cierto conocimiento de \unix\ ---conocimiento que tal vez
Ud. no tenga en este momento.  Cuando termine de leer la página, es
probable que vea un bloque en video inverso al final de la página,
parecido a ``{\tt --more--}'' o a ``{\tt Line 1}''.  Se trata del
\concept{pedido de más} (información), que pronto le será muy
familiar.

En lugar de dejar escapar el texto fuera de los límites de la
pantalla, \cmdnm{man} se detiene al final de cada página, y espera
para ver que ha decidido hacer Ud..  Si desea seguir leyendo, oprima
\key{Barra espaciadora} y avanzará una página.  Si desea terminar con
la lectura de la página del manual, oprima \key{q}.  Regresará
entonces al prompt del shell, que esperará hasta que Ud. escriba otro
comando.

\cmdnm{man} provee además una función de búsqueda de palabras clave.
Por ejemplo, digamos que Ud. está interesado en el tema PostScript, el
lenguaje de control de impresoras desarrollado por Adobe.  Si escribe
\cmdln{man -k ps} o \cmdln{man -k Postscript}, recibirá como resultado
una lista de todos los comandos, llamadas al sistema, y otras partes
documentadas de \unix\ que contengan la palabra ``ps'' (o
``Postscript'') en su nombre o descripción breve.  Esto puede llegar a
ser muy útil cuando quiere buscar una herramienta para hacer algo,
pero no conoce su nombre ---o si existe.

\eindex{help!on-line}
\section{Almacenaje de la información}

Los filtros son muy útiles cuando Ud. se ha transformado en un usuario
experimentado, pero tienen un pequeño problema.  ¿Cómo almacena Ud.
la información.  Seguramente, ¡no se espera que Ud.  teclee todas las
cosas cada vez que desea utilizar el programa!  Por supuesto que no.
\unix\ provee {\bf archivos} y {\bf directorios}\glossary{directorio}.

Un directorio es como una carpeta, contiene hojas de papel, o
archivos.  Una carpeta suficientemente grande puede contener otras
carpetas---puede haber directorios dentro de directorios.  En \unix,
se denomina sistema de archivo\index{sistema de archivo} a la
colección de archivos y directorios.  Inicialmente en el sistema de
archivo sólo existe un directorio, denominado ``root''\footnote{N. del
  T.: directorio {\em
    raíz}.}\index{directorio!raiz}\index{directorio!root}.  Dentro de
este directorio hay más directorios, y dentro de ellos hay archivos, y
aún más directorios\footnote{Puede haber o no un límite a la
  ``profundidad'' a la cual puede llegar el sistema de archivo. (En mi
  caso nunca la alcancé---uno fácilmente puede tener directorios de 10
  niveles de profundidad.)}.

Cada archivo y cada directorio tiene un nombre.  Nos referiremos a su
\concept{nombre corto}\footnote{N. del T.: Nombre relativo del archivo
  o directorio.} ---que puede coincidir con el de otro archivo y/o
directorio en alguna otra parte del sistema de archivo, y al
\concept{nombre largo}\footnote{N. del T.: Nombre completo o
  absoluto.}  ---que es único.  Un nombre corto para un archivo puede
ser \file{joe}, mientras que su \concept{nombre completo} podría ser
\file{/home/larry/joe}.  El nombre completo se denomina usualmente
{\bf trayectoria}\footnote{N. del T.: {\em trayectoria\/} del inglés
  {\em path}.}\glossary{path}.  La trayectoria puede decodificarse
como una secuencia de directorios.  Por ejemplo, veremos como se lee
\file{/home/larry/joe}:

\begin{tabbing}
  \tt /\=\tt home/\=\tt larry/\=\tt joe\\
  \parbox{12cm}{La barra inicial indica el directorio raíz.}\+\\
  \parbox{12cm}{Aquí esta el directorio denominado
    \file{home}. Está dentro del directorio raíz.}\+\\
  \parbox{12cm}{Este es el directorio \file{larry}, el cual está
    dentro de \file{home}.}\+\\
  \parbox{12cm}{\file{joe} está dentro de \file{larry}.  Una
    trayectoria puede referirse tanto a un directorio como a un nombre
    de archivo, así que \file{joe} podría ser cualquiera de ellos.
    Todos los items {\em antes\/} del nombre corto deben ser
    directorios.}
\end{tabbing}

Una manera sencilla de visualizar todo esto es mediante un diagrama en
árbol.  Para ver el diagrama de un sistema típico \linux, mire la
Figura~\ref{standard-dirtree}.  Debe Ud. notar que dicho diagrama no
está completo ---¡un sistema \linux\ completo tiene más de 8000
archivos!--- y sólo muestra algunos de los directorios estándar.  Por
lo tanto, puede haber algunos directorios del diagrama que no estén en
su sistema, y de hecho su sistema tendrá directorios que no aparecen
en la figura.

\unitlength=1.0pt
\begin{figure}[bt]
\caption{Típico árbol (podado) de directorios Unix.}
\label{standard-dirtree}
\begin{picture}(148.00,365.00)(0.00,450.00)
\put(9.00,805.00){\line(1,0){29.00}} % / -> bin
\put(26.00,805.00){\line(0,-1){112.00}} % /'s children
\put(26.00,791.00){\line(1,0){12.00}} % dev
\put(26.00,777.00){\line(1,0){12.00}} % etc
\put(26.00,763.00){\line(1,0){12.00}} % home
\put(64.50,763.00){\line(1,0){29.00}} % home -> larry
\put(81.50,763.00){\line(0,-1){14.00}} % home's children
\put(81.50,749.00){\line(1,0){12.00}} % sam
\put(26.00,735.00){\line(1,0){12.00}} % lib
\put(26.00,721.00){\line(1,0){12.00}} % proc
\put(26.00,707.00){\line(1,0){12.00}} % tmp
\put(26.00,693.00){\line(1,0){12.00}} % usr
\put(55.50,693.00){\line(1,0){29.00}} % usr -> X386
\put(72.50,693.00){\line(0,-1){238.00}} % usr's children
\put(72.50,676.00){\line(1,0){12.00}} % bin
\put(72.50,659.00){\line(1,0){12.00}} % emacs
\put(72.50,642.00){\line(1,0){12.00}} % etc
\put(72.50,625.00){\line(1,0){12.00}} % g++-include
\put(72.50,608.00){\line(1,0){12.00}} % include
\put(72.50,591.00){\line(1,0){12.00}} % lib
\put(72.50,574.00){\line(1,0){12.00}} % local
\put(107.00,574.00){\line(1,0){29.00}} % local -> bin
\put(124.00,574.00){\line(0,-1){51.00}} % local's children
\put(124.00,557.00){\line(1,0){12.00}} % emacs
\put(124.00,540.00){\line(1,0){12.00}} % etc
\put(124.00,523.00){\line(1,0){12.00}} % lib
\put(72.50,506.00){\line(1,0){12.00}} % man
\put(72.50,489.00){\line(1,0){12.00}} % spool
\put(72.50,472.00){\line(1,0){12.00}} % src
\put(100.50,472.00){\line(1,0){29.00}} % src -> linux
\put(72.50,455.00){\line(1,0){12.00}} % tmp
\put(8.50,805.00){\makebox(0,0)[rc]{/}}
\put(39.50,805.00){\makebox(0,0)[lc]{bin}}
\put(39.50,791.00){\makebox(0,0)[lc]{dev}}
\put(39.50,777.00){\makebox(0,0)[lc]{etc}}
\put(39.50,763.00){\makebox(0,0)[lc]{home}}
\put(95.00,763.00){\makebox(0,0)[lc]{larry}}
\put(95.00,749.00){\makebox(0,0)[lc]{sam}}
\put(39.50,735.00){\makebox(0,0)[lc]{lib}}
\put(39.50,721.00){\makebox(0,0)[lc]{proc}}
\put(39.50,707.00){\makebox(0,0)[lc]{tmp}}
\put(39.50,693.00){\makebox(0,0)[lc]{usr}}      % I'm expecting you to
\put(86.00,693.00){\makebox(0,0)[lc]{X11R6}}    % proof-read this!
\put(86.00,676.00){\makebox(0,0)[lc]{bin}}      
\put(86.00,659.00){\makebox(0,0)[lc]{emacs}}    % I am, I am, don't worry! :-)
\put(86.00,642.00){\makebox(0,0)[lc]{etc}}
\put(86.00,625.00){\makebox(0,0)[lc]{g++-include}}
\put(86.00,608.00){\makebox(0,0)[lc]{include}}
\put(86.00,591.00){\makebox(0,0)[lc]{lib}}
\put(86.00,574.00){\makebox(0,0)[lc]{local}}
\put(137.50,574.00){\makebox(0,0)[lc]{bin}}
\put(137.50,557.00){\makebox(0,0)[lc]{emacs}}
\put(137.50,540.00){\makebox(0,0)[lc]{etc}}
\put(137.50,523.00){\makebox(0,0)[lc]{lib}}
\put(86.00,506.00){\makebox(0,0)[lc]{man}}
\put(86.00,489.00){\makebox(0,0)[lc]{spool}}
\put(86.00,472.00){\makebox(0,0)[lc]{src}}
\put(130.50,472.00){\makebox(0,0)[lc]{linux}}
\put(86.00,455.00){\makebox(0,0)[lc]{tmp}}
\end{picture}
\end{figure}

\subsection{Miremos los directorios con \cmdnm{ls}}

Ahora que ya sabe de la existencia de archivos y directorios, debe
haber también una manera de manipularlos.  Por supuesto.  El comando
\cmdnm{ls}\ttindex{ls} es uno de los más importantes, y lo que hace es
{\bf l}i{\bf s}tar los archivos.  Si prueba a correr el comando
\cmdln{ls}, entonces verá:

\begin{screen}\begin{verbatim}
/home/larry$ ls
/home/larry$
\end{verbatim}\end{screen}
    
Está bien, no se preocupe por no ver nada.  \unix\ es intencionalmente
callado: si no hay archivos para mostrar, no muestra nada (ni siquiera
un ``no hay archivos'').  Por lo tanto, la ausencia de salida es la
manera de \cmdnm{ls} de decir que no encontró ningún archivo.

Pero hace un momento dije que hay más de 8000 archivos por allí:
¿dónde están?  Acaba de encontrar el concepto de directorio
``actual''.  Como puede ver en el prompt, su directorio actual es
\file{/home/larry} y allí no hay archivos.  Si desea la lista de
archivos de un directorio más poblado, pruebe con el directorio raíz:

\begin{screen}\begin{verbatim}
/home/larry$ ls /
bin      etc      install  mnt      root     user     var
dev      home     lib      proc     tmp      usr      vmlinux
/home/larry$ 
\end{verbatim}
\end{screen}

En el comando anterior, \cmdln{ls /}, el directorio (\cmdln{/}) es lo
que se denomina un \concept{parámetro}.  La primer palabra de un
comando es el nombre del comando, y cualquier cosa que le siga son sus
parámetros.  Los parámetros generalmente modifican la forma en la que
actúa un programa---para \cmdnm{ls}, el parámetro le dice de cual
directorio desea Ud.\ la lista de archivos.  Algunos comandos tienen
parámetros especiales denominados opciones o interruptores\footnote{N.
  del T.: {\em interruptores\/} del inglés {\em switches}.}  Para ver
esto, pruebe:

\begin{screen}\begin{verbatim}
/home/larry$ ls -F /
bin/      etc/      install/  mnt/      root/     user/     var@
dev/      home/     lib/      proc/     tmp/      usr/      vmlinux
/home/larry$ 
\end{verbatim}
\end{screen}

El \cmdln{-F} es una \concept{opción}.  Las opciones son clases
especiales de parámetros que comienzan con un guión y modifican el
funcionamiento del programa.  Para \cmdln{ls}, \cmdln{-F} es una
opción que le permite a Ud. ver cuales de las entradas son
directorios, cuales son archivos especiales, cuales programas, y
cuales son archivos normales.  Cualquiera que termina con una barra es
un directorio.  Trataremos con más detalle las características de
\cmdnm{ls} más adelante.  ¡Es un programa sorprendentemente complejo!

Por ahora, hay dos lecciones que se deben aprender.  Primero, debe
aprender que es lo que hace\tie\cmdnm{ls}.  Pruebe unos cuantos otros
directorios de los que se muestran en el árbol de la
Figura~\ref{standard-dirtree}, y fíjese en su contenido.
Naturalmente, algunos estarán vacíos, y otros tendrán muchos archivos
dentro.  Le sugiero que utilice~\cmdln{ls} con y sin la
opción~\cmdln{-F}.  Por ejemplo, \cmdln{ls /usr/local} debe aparecer
más o menos así:

\begin{screen}\begin{verbatim}
/home/larry$ ls /usr/local
archives  bin       emacs     etc       ka9q      lib       tcl
/home/larry$ 
\end{verbatim}
\end{screen}

La segunda lección es más general.  Muchos comandos \unix\ son como
\cmdnm{ls}.  Tienen opciones, que en general consisten de un carácter
precedido por un guión, y tienen parámetros.  A diferencia de
\cmdnm{ls}, algunos comandos \emph{requieren} ciertos parámetros y/u
opciones.  Para mostrar como se usan los comandos, utilizaremos el
siguiente formato:


\begin{command}
{\tt ls} [-aRF] [{\sl directorio}]
\end{command}

En general, y desde ahora en adelante, utilizaré plantillas de
comandos como la mostrada, antes de introducir comandos nuevos para
Ud..  La primer palabra es el comando (en este caso \cmdnm{ls}).  A
continuación del comando siguen todos los parámetros.  Los parámetros
opcionales se encerrarán entre corchetes (``{\tt [}'' y ``{\tt ]}'').
Las meta-variables están {\sl inclinadas\/}---son palabras que toman
el lugar de los parámetros reales.  (Por ejemplo, más arriba puede Ud.
ver que dice {\sl directorio}, lo cual debe ser reemplazado por el
nombre de un directorio real.)

Las opciones son un caso especial.  Están encerradas entre corchetes,
pero Ud. puede utilizar una sola de ellas sin necesidad de emplear
todas juntas.  Por ejemplo, con las tres opciones enumeradas más
arriba para el caso de \cmdnm{ls}, Ud.  tiene ocho maneras posibles de
correr el comando: con o sin cada una de las opciones.  (Contraste
\cmdln{ls -R} con \cmdln{ls -F}.)

\subsection{El directorio actual y \cmdnm{cd}}

\begin{command}
{\tt pwd}
\end{command}

El uso de los directorios puede ser insoportable si se tiene que
teclear la trayectoria completa cada vez que se quiere acceso a un
directorio.  En lugar de ello, los shell de \unix\ tienen una
característica denominada directorio ``actual'', ``presente'', o ``de
trabajo''.  Es muy probable que su configuración de shell muestre
dicho directorio como parte del prompt: \file{/home/larry}.  Si no lo
hace, pruebe el comando \cmdnm{pwd}, que proviene de la sigla de las
palabras {\bf p}resent {\bf w}orking {\bf d}irectory\footnote{N. del
  T.: Directorio de trabajo actual.}.  (Algunas veces el prompt
muestra el nombre de la máquina.  Esto sólo es útil realmente en un
entorno de red en el cual hay una gran cantidad de máquinas
diferentes.)\ttindex{pwd} \index{directorio!actual}
\index{directorio!presente} \index{directorio!de trabajo}
\index{directory!current} \index{directory!present}
\index{directory!working}

\begin{screen}\begin{verbatim}
mousehouse>pwd
/home/larry
mousehouse>  
\end{verbatim}
\end{screen}

\begin{command}
{\tt cd} [{\sl directorio}]
\end{command}

Como puede Ud. ver, \cmdnm{pwd} le dice cuál es su directorio
actual\footnote{En este libro verá todos los términos en uso:
  directorio de trabajo presente, directorio actual, o directorio de
  trabajo.  Prefiero ``directorio actual'', aunque a veces recurra a
  las otras formas a causa de razones de estilo.}--- se trata de un
comando muy simple.  La mayoría de los comandos actúa, de forma
predeterminada, sobre el directorio actual.  Podemos cambiar nuestro
directorio actual mediante el comando \cmdnm{cd}\ttindex{cd}.  Por
ejemplo, pruebe:

\begin{screen}\begin{verbatim}
/home/larry$ cd /home
/home$ ls -F
larry/     sam/       shutdown/  steve/     user1/
/home$ 
\end{verbatim}
\end{screen}% $

Si Ud. omite el parámetro opcional {\sl directorio}, se lo retornará a
su directorio raíz personal, o directorio original.  De otro modo,
\cmdnm{cd} lo cambiará al directorio especificado.  Por ejemplo:

\begin{screen}\begin{verbatim}
/home$ cd
/home/larry$ cd /
/$ cd home
/home$ cd /usr
/usr$ cd local/bin
/usr/local/bin$
\end{verbatim}
\end{screen}

Como puede ver, \cmdnm{cd} le permite expresar el directorio de
destino con trayectorias absolutas o relativas.  Una
\concept{trayectoria absoluta} comienza con una ``{\tt /}'' y
especifica todos lo directorios que existen antes del archivo que Ud.
desea.  Una \concept{trayectoria relativa} está referida a su
directorio actual.  En el ejemplo anterior, cuando estaba en ``{\tt
  /usr}'', hice un movimiento relativo a ``\file{local/bin}''---``{\tt
  local}'' es un directorio que existe bajo ``\file{/usr}'', y
``\file{bin}'' es un directorio bajo ``\file{local}''.  (\cmdln{cd
  home} también fue un cambio de directorio relativo.)

Existen dos directorios que se utilizan {\rm solamente\/} para
trayectorias relativas: ``{\tt .}'' y ``{\tt
  ..}''\index{directorio!actual}\index{directorio!antecesor}.  El
directorio ``{\tt .}'' se refiere al directorio actual, y ``{\tt ..}''
es el directorio anterior: son ``abreviaturas'' de directorio, y
existen en {\em todos\/} los directorios, aunque no cuadran bien en la
metáfora de ``carpeta dentro de carpeta''.  Aún el directorio raíz
tiene un directorio anterior: él es su propio directorio anterior.

El archivo \file{./chapter-1} viene a ser el archivo \file{chapter-1}
que está en el directorio actual.  Ocasionalmente, será necesario que
Ud. coloque explícitamente el ``{\tt ./}'' para que ciertos comandos
funcionen, aunque esto es raro.  En la mayoría de los casos, dará
igual poner \file{./chapter-1} o \file{chapter-1}.

El directorio ``{\tt ..}'' es más útil cuando queremos ``retroceder'':

\begin{screen}\begin{verbatim}
/usr/local/bin$ cd ..
/usr/local$ ls -F
archives/  bin/       emacs@     etc/       ka9q/      lib/       tcl@
/usr/local$ ls -F ../src
cweb/      linux/     xmris/
/usr/local$
\end{verbatim}\end{screen}%
    
En este ejemplo, me cambié al directorio anterior mediante \cmdln{cd
  ..} y luego listé el directorio \file{/usr/src} desde
\file{/usr/local} utilizando el nombre \file{../src}.  Debe advertir
que si hubiese estado en \file{/home/larry}, ejecutar el comando
\cmdln{ls -F ../src} no me habría servido al propósito de ver lo que
hay en \file{/usr/src}.

El directorio ``{\tt \verb+~+/}'' es un alias para su directorio
personal\index{directorio!personal}:

\begin{screen}\begin{verbatim}
/usr/local$ ls -F ~/
/usr/local$ 
\end{verbatim}\end{screen}
    
Puede ver que aún no hay nada en su directorio personal.  ``{\tt
  \verb+~+/}'' será más útil a medida que aprendamos más acerca de
como manipular los archivos.

\subsection{Creación y borrado de directorios}

\index{mkdir@{\tt mkdir}|(}\bindex{directorio!creación} 

\begin{command}
{\tt mkdir} {\sl directorio1} [{\sl directorio2 \ldots directorioN}]
\end{command}

En \unix, crear directorios es extremadamente simple, y puede ser una
muy útil herramienta de organización.  Para crear un nuevo directorio,
utilice el comando \cmdnm{mkdir}.  Por supuesto, \cmdnm{mkdir} viene
de {\bf m}a{\bf k}e {\bf dir}ectory\footnote{N. del T.: Crear
  directorio.}.

Con un pequeño ejemplo, veamos como funciona esto:
\begin{screen}\begin{verbatim}
/home/larry$ ls -F
/home/larry$ mkdir report-1993
/home/larry$ ls -F
report-1993/
/home/larry$ cd report-1993
/home/larry/report-1993$
\end{verbatim}
\end{screen}% $

\cmdnm{mkdir} puede tomar más de un parámetro, a los que interpreta
como nombres de directorios que debe crear.  Puede especificarlos
mediante su nombre relativo o absoluto; \file{report-1993} es un caso
de ejemplo con trayectoria relativa.

\begin{screen}\begin{verbatim}
/home/larry/report-1993$ mkdir /home/larry/report-1993/chap1 ~/report-1993/chap2
/home/larry/report-1993$ ls -F
chap1/  chap2/
/home/larry/report-1993$
\end{verbatim}\end{screen}% $

\begin{command}
  {\tt rmdir} {\sl directorio1} [{\sl directorio2 \ldots directorioN}]
\end{command}

El opuesto de \cmdnm{mkdir} es \cmdnm{rmdir} ({\bf r}e{\bf m}ove {\bf
  dir}ectory\footnote{N. del T.: Eliminar directorio.}).
\cmdnm{rmdir} trabaja exactamente igual que
\cmdnm{mkdir}\ttindex{rmdir}.

Un ejemplo de \cmdnm{rmdir} es:

\begin{screen}\begin{verbatim}
/home/larry/report-1993$ rmdir chap1 chap3
rmdir: chap3: No such file or directory
/home/larry/report-1993$ ls -F
chap2/
/home/larry/report-1993$ cd ..
/home/larry$ rmdir report-1993
rmdir: report-1993: Directory not empty
/home/larry$
\end{verbatim}\end{screen}% $

Como puede apreciar, \cmdnm{rmdir} se niega a borrar un directorio que
no existe, y tampoco permite eliminar directorios que tengan algo
dentro.  (Recuerde que \file{report-1993} tiene un subdirectorio,
\file{chap2}, dentro de él) Existe un tema interesante para pensar,
entonces: ¿qué pasa si intenta eliminar su directorio actual?
Averigüémoslo:

\begin{screen}\begin{verbatim}
/home/larry$ cd report-1993
/home/larry/report-1993$ ls -F
chap2/
/home/larry/report-1993$ rmdir chap2
/home/larry/report-1993$ rmdir .
rmdir: .: Operation not permitted
/home/larry/report-1993$
\end{verbatim}\end{screen}% $

Otra situación del mismo estilo, es que sucede si intenta eliminar el
directorio anterior al directorio actual.  Bien, esto no es un
problema nuevo: el directorio anterior al actual no está vacío (existe
el actual en él), así que no puede ser borrado.  \index{mkdir@{\tt
    mkdir}|)}\eindex{directorio!creación}


\section{Información en movimiento}

Todos este asunto de los directorios está muy lindo, pero no son de
ninguna ayuda, a menos que Ud. tenga algún sitio donde almacenar sus
datos.  Los dioses\index{dioses!\unix} del \unix\ vieron este problema
y lo solucionaron haciendo que los usuarios tengan
\concept{archivos}\footnote{N. del T.: También denominados {\em
    ficheros}.}

Aprenderemos más acerca de la creación y edición de archivos en los
próximos capítulos.

Los comandos básicos para manipular archivos en \unix\ son \cmdnm{cp},
\cmdnm{mv}, y \cmdnm{rm}.  Sus nombres provienen de {\bf c}o{\bf
  p}y\footnote{N. del T.: Copiar.}, {\bf m}o{\bf v}e\footnote{N. del
  T.: Mover.}, y {\bf r}e{\bf m}ove\footnote{N.  del T.: Quitar,
  borrar.}, respectivamente.

\subsection{\cmdnm{cp} como un monje}\bttindex{cp}

\begin{command}
  {\tt cp} [-i] {\sl fuente} {\sl destino}\\ {\tt cp} [-i] {\sl
    archivo1 archivo2 \ldots archivoN} {\sl
    directorio-de-destino}\footnote{\cmdnm{cp} necesita de dos
    renglones en su plantilla porque el significado del segundo
    parámetro depende de la cantidad de parámetros.}
\end{command}

\cmdnm{cp} es una utilidad muy práctica en \unix, y además muy
poderosa.  Permite que una persona pueda copiar más información en un
segundo que lo que podía copiar un monje del siglo XIV en todo un año.

\cautionpar Debe ser muy cuidadoso con \cmdnm{cp} si no dispone de una
cantidad importante de espacio en disco.  A nadie le hace gracia ver
el mensaje ``Disk full''\footnote{N. del T.: Disco lleno.} cuando está
trabajando con archivos importantes.  \cmdnm{cp} también puede
sobreescribir archivos existentes sin previo aviso ---trataremos este
tema más adelante.

Bien, hablaremos primero acerca de la primer línea en la plantilla del
comando.  El primer parámetro de \cmdnm{cp} es el nombre del archivo
que hay que copiar, el segundo es el lugar donde se desea depositar la
copia.  Puede obtener una copia con un nombre distinto, o una en un
directorio diferente.  Veamos algunos ejemplos:

\begin{screen}\begin{verbatim}
/home/larry$ ls -F /etc/passwd
/etc/passwd
/home/larry$ cp /etc/passwd .
/home/larry$ ls -F
passwd
/home/larry$ cp passwd frog
/home/larry$ ls -F
frog  passwd
/home/larry$
\end{verbatim}
\end{screen}

El primer comando \cmdnm{cp} que corrí tomó el archivo
\file{/etc/passwd}\ttindex{/etc/passwd}, que contiene los nombres
% y las palabras clave << lo quité por el shadow (cb)
de todos los usuarios en un sistema \unix, y lo copió en mi
directorio raíz.  \cmdnm{cp} no borra el archivo fuente, así
que no hice nada que pudiera dañar el sistema.  O sea que ahora
existen dos copias del contenido del archivo \file{/etc/passwd}, ambas
se denominan \file{passwd}, pero una está en el directorio
\file{/etc} y la otra en \file{/home/larry}.

Luego, creamos una {\em tercera\/} copia de \file{/etc/passwd} cuando
tecleamos \cmdln{cp passwd frog} ---ahora hay tres copias:
\file{/etc/passwd}, \file{/home/larry/passwd} y
\file{/home/larry/frog}.  El contenido de esos tres archivos es el
mismo, sus nombres de archivo difieren.

\cmdnm{cp} puede copiar archivos entre directorios si el primer
parámetro es un archivo y el segundo es un directorio.  En este caso,
el nombre simple (sin el path) de destino coincidirá con el original,
para cada archivo.

También se puede copiar un archivo y cambiar su nombre de destino en
una sola operación, caso que se da cuando ambos parámetros son nombres
de archivo.  Aquí reside uno de los peligros de \cmdnm{cp}.  Si
tecleara \cmdln{cp /etc/passwd /etc/group}, el comando \cmdnm{cp}
crearía normalmente un archivo nuevo con el contenido idéntico al de
\file{/etc/passwd} y con el nombre \file{/etc/group}. Por lo tanto, si
\file{/etc/group} ya existiera, \cmdnm{cp} destruiría el contenido del
antiguo sin darle la oportunidad de guardarlo.  (Ni siquiera escribirá
un mensaje en el cual le advierta que está por destruir un archivo al
copiarle otro encima.)

Echemos una mirada a otro ejemplo de \cmdnm{cp}:
\begin{screen}\begin{verbatim}
/home/larry$ ls -F
frog  passwd
/home/larry$ mkdir passwd_version
/home/larry$ cp frog passwd passwd_version
/home/larry$ ls -F
frog         passwd        passwd_version/
/home/larry$ ls -F passwd_version
frog  passwd
/home/larry$
\end{verbatim}
\end{screen}

¿Cómo usé \cmdnm{cp} en este caso?  Evidentemente, \cmdnm{cp} puede
tomar {\em más\/} de dos parámetros, como se puede apreciar en la
segunda línea de plantillas del comando.  Lo que el comando anterior
realizó es copiar los archivos que aparecen listados (\file{frog}, y
\file{passwd}) al directorio \file{passwd\_version}.  De hecho,
\cmdnm{cp} puede tomar cualquier número de parámetros: interpreta los
primeros $n-1$ como los nombres de archivo que debe copiar, y el
$n^{\rm \acute{e}simo}$ parámetro como el nombre del directorio al
cual se deben copiar los anteriores.


\cautionpar No puede renombrar archivos cuando copia más de uno a la
vez---siempre mantienen su nombre simple.  Esto nos lleva a una
pregunta interesante.  ¿Qué es lo que pasaría si tecleamos \cmdln{cp
  frog passwd toad}, donde \file{frog} y \file{passwd} existen, y
\file{toad} no es un directorio?  Inténtelo y lo sabrá.  \ettindex{cp}

\subsection{La poda con \cmdnm{rm}}\bttindex{rm}

\begin{command}
  {\tt rm} [-i] {\sl archivo1 archivo2 \ldots archivoN}
\end{command}

Ahora que hemos aprendido como crear millones de archivos con
\cmdnm{cp}\ttindex{cp} (y créame, muy pronto encontrará nuevas maneras
de crear más archivos), sería útil aprender la manera de borrarlos.
De hecho, es muy simple: el comando que anda necesitando es
\cmdnm{rm}, y funciona como Ud. se lo esperaría: a cualquier archivo
cuyo nombre se pasa como parámetro a {\tt rm} se lo borra.

Por ejemplo:
\begin{screen}\begin{verbatim}
/home/larry$ ls -F
frog         passwd        passwd_version/
/home/larry$ rm frog toad passwd
rm: toad: No such file or directory
/home/larry$ ls -F
passwd_version/
/home/larry$
\end{verbatim}\end{screen}

Como puede Ud. apreciar, \cmdnm{rm} es extremadamente espartano.  No
sólo no pide su confirmación, sino que borra cosas aún en el caso en
que haya errores en la línea de comandos.  Esto bien puede ser
peligroso. Considere la diferencia entre estos dos comandos:
\begin{screen}\begin{verbatim}
/home/larry$ ls -F
toad  frog/
/home/larry$ ls -F frog
toad
/home/larry$ rm frog/toad
/home/larry$
\end{verbatim}\end{screen}
y este otro:
\begin{screen}\begin{verbatim}
/home/larry$ rm frog toad
rm: frog is a directory
/home/larry$ ls -F
frog/
/home/larry$
\end{verbatim}\end{screen}% $

\cautionpar Como puede ver, la diferencia en {\em un\/} caracter hace
una diferencia importante en la salida del comando. ¡Es vital que Ud.
controle lo que ha escrito en sus líneas de comando antes de presionar
\ret!  \ettindex{rm}

\subsection{Sería interesante tener un rastrillo}\bttindex{mv}

\begin{command}
  {\tt mv} [-i] {\sl nombre-viejo} {\sl nombre-nuevo}\\
  {\tt mv} [-i] {\sl archivo1 archivo2 \ldots archivoN} {\sl
    nuevo-directorio}
\end{command}

Por último, el otro comando del que debe cuidarse es \cmdnm{mv}.
\cmdnm{mv} se parece un montón a \cmdnm{cp}, excepto que borra el
archivo original después de copiarlo.  Se puede entender como la
utilización conjunta de \cmdnm{cp} y \cmdnm{rm}.  Veamos que podemos
hacer:

\begin{screen}\begin{verbatim}
/home/larry$ cp /etc/passwd .
/home/larry$ ls -F
passwd
/home/larry$ mv passwd frog
/home/larry$ ls -F
frog
/home/larry$ mkdir report
/home/larry$ mv frog report
/home/larry$ ls -F
report/
/home/larry$ ls -F report
frog
/home/larry$
\end{verbatim}\end{screen}% $
    
Como puede ver, \cmdnm{mv} renombra un archivo (que es el primer
parámetro) si el segundo parámetro es un archivo.  Si el segundo
parámetro es un directorio, \cmdnm{mv} moverá el archivo al nuevo
directorio, manteniendo el mismo nombre simple.

\cautionpar Debe Ud. ser muy cuidadoso con \cmdnm{mv} ---el comando no
controla si el archivo ya existe, y borrará cualquier archivo que
hubiera con el nombre de destino.  Por ejemplo, si ya tengo un archivo
de nombre \file{frog} existente en mi directorio \file{report}, el
comando \cmdln{mv frog report} borrará el archivo
\file{\tie/report/frog} y lo reemplazará con \file{\tie/frog}.

De hecho, existe una manera de lograr que tanto \cmdnm{rm},
\cmdnm{cp}, y \cmdnm{mv} le consulten a Ud.\ antes de eliminar
archivos.  Los tres comandos nombrados aceptan la opción \cmdln{-i} a
tal efecto.  Si Ud. utiliza un {\bf alias} puede hacer que el shell
ejecute: \cmdln{rm -i} automáticamente cuando teclee: \cmdln{rm}.
Aprenderá más de estos temas luego en la
Sección~\ref{aliasing-section} en la
página~\pageref{aliasing-section}.

\ettindex{mv}

% Local Variables: 
% mode: latex
% TeX-master: "guide"
% End:
