<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[a4paper, 12pt]{article}

%
% Apunte curso inicial de GNU/Linux
% Copyright (C) 2008  Maximiliano Curia y Margarita Manterola
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
%

\usepackage{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[spanish]{babel}

\addtolength{\oddsidemargin}{-.875in}
\addtolength{\evensidemargin}{-.875in}
\addtolength{\textwidth}{1.75in}
\addtolength{\topmargin}{-.875in}
\addtolength{\textheight}{1.75in}

\title{Curso de GNU/Linux para principiantes}
\author{Margarita Manterola \and Maximiliano Curia}
\date{Facultad de IngenierÃ­a - UBA \\ Actualizado Octubre 2004}

\begin{document}

\maketitle

%\tableofcontents

%\newpage

\section{Conociendo GNU/Linux}

GNU/Linux es un sistema operativo derivado de UNIX, que se distribuye en forma
libre.

\subsection{QuÃ© es UNIX}

UNIX es un sistema operativo multitarea, multiusuario, creado en 1969 por
los investigadores Thompson y Ritchie de los Laboratorios Bell, en los
Estados Unidos.  Las primeras versiones fueron escritas en assembler, pero muy
pronto fue re-escrito en lenguaje C.

En sus primeros aÃ±os, no se lo utilizÃ³ comercialmente, sino que se lo
usaba para proyectos de investigaciÃ³n en laboratorios
y se distribuÃ­a gratuitamente en las universidades, donde tuvo mucha
aceptaciÃ³n.

En 1975, Bell decidiÃ³ comercializarlo.  Dado que el sistema se vendÃ­a con
una licencia que permitÃ­a modificarlo y redistribuirlo, a lo largo del tiempo
fueron surgiendo una gran variedad de sistemas derivados del UNIX original.  
Los mÃ¡s conocidos, actualmente, son: Solaris, AIX, HPUX, SCO, BSD.

Por esta razÃ³n, varias veces se hizo necesario normalizar estos sistemas,
para que cumplan con determinadas normas (POSIX, UNIX95, etc), para permitir
la compatibilidad entre los diferentes sistemas.

De estas normas, el sistema operativo GNU/Linux satisface la norma POSIX-1, y
casi completamente la POSIX-2.

\subsection{QuÃ© es GNU}

La sigla GNU significa {\it GNU is Not Unix}.

En 1984, Richard Stallman fundÃ³ el Proyecto GNU con el objetivo de 
conseguir un sistema operativo libre y abierto. Esto es, un sistema
operativo tal que los usuarios puedan usarlo,
leer el cÃ³digo fuente, modificarlo, y redistribuirlo.

A partir de ese momento, un gran nÃºmero de colaboradores se fueron sumando
al proyecto, desarrollando software libre para reemplazar cada una de las
herramientas del sistema UNIX. 

La filosofÃ­a GNU apoya el crecimiento de la sociedad como un conjunto,
haciendo especial hincapiÃ© en la valoraciÃ³n de las libertades personales,
aÃºn cuando esto puede estar en conflicto con intereses empresariales.

\subsection{QuÃ© es Linux}

En 1991, Linus Torvalds completÃ³ el sistema con su kernel (que es la
aplicaciÃ³n encargada de comunicar los procesos con el hardware de la 
computadora).  A este kernel lo bautizÃ³ Linux.

De esta manera, se formÃ³ el sistema GNU/Linux.

\subsection{QuÃ© es BSD}

La Universidad de Berkeley estuvo relacionada con el desarrollo de los sistemas
operativos UNIX.  RecibiÃ³ de AT\&amp;T una versiÃ³n gratuita de UNIX, y a partir de
entonces comenzÃ³ a promover el desarrollo de aplicaciones para UNIX dentro de la
universidad.

Mas adelante, desarrollo su propio sistema operativo UNIX, sin utilizar el
cÃ³digo fuente de AT\&amp;T.  El kernel fue creado desde Berkeley, pero las
herramientas utilizadas son en su mayorÃ­a GNU, es decir las mismas que en el
sistema GNU/Linux.

Existen actualmente 3 sistemas operativos libres, derivado de BSD: FreeBSD,
OpenBSD y NetBSD.


\subsection{QuÃ© es X}

El sistema operativo GNU/Linux cuenta con una interfaz grÃ¡fica, llamada 
XFree86 o simplemente X.

El protocolo X fue desarrollado por el MIT, principalmente como un logro
acadÃ©mico para proporcionar un entorno grÃ¡fico a UNIX.  La licencia
mediante la cual se distribuye permite usarlo, modificarlo, redistribuirlo
e incluso re-licenciarlo.

\subsection{QuÃ© son las distribuciones}

El cÃ³digo fuente del sistema GNU y del kernel Linux estÃ¡ accesible a todo
el mundo, sin embargo, hacer funcionar un sistema a partir del cÃ³digo fuente
es bastante difÃ­cil.  Por eso, un sistema operativo se distribuye
(normalmente) en formato binario, es decir {\bf ya compilado}.

Poco despuÃ©s de que apareciera el kernel Linux, comenzaron a aparecer las
primeras distribuciones, que agrupaban versiones probadas de varios programas,
junto con el kernel, de tal manera que formaban un sistema operativo listo para
usar.

A medida que fue pasando el tiempo, algunas distribuciones se fueron haciendo
mÃ¡s sofisticadas, otras desaparecieron, otras se hicieron comerciales y
aparecieron mucha mÃ¡s.  Existen distribuciones de muchos tipos: distribuciones
que ocupan 1 diskette y distribuciones que llegan a ocupar 10 CDs;
distribuciones orientadas a una finalidad en especial (redes, seguridad,
etc) y distribuciones de uso general.

Cada usuario de GNU/Linux suele elegir la distribuciÃ³n con la que se siente
mÃ¡s cÃ³modo, y no tiene sentido entrar en discusiones acerca de cuÃ¡l es
mejor.

A menos que aclaremos lo contrario, lo que se enseÃ±a en este curso es
aplicable a la gran mayorÃ­a de los sistemas UNIX, y a cualquiera de las
distribuciones de GNU/Linux.

\subsection{QuÃ© son las plataformas}

El mundo de las computadoras no se restringe a las Computadoras Personales
con las que estamos en contacto todos los dÃ­as.  Existen
diversas arquitecturas en las que una computadora se puede presentar.  A cada
una de estas arquitecturas la llamamos {\it plataforma}.

Ejemplos de algunas plataformas posibles son: iMac (de
Macintosh), Sparc (de Sun), S/390 (de IBM), PlayStation (de Sony), XBox (de
Microsoft).

En particular, la plataforma que utilizamos comÃºnmente se la denomina {\it
i386}, ya que estÃ¡ basada en los procesadores de Intel, a partir del 386.

\subsection{Por quÃ© aprender acerca de GNU/Linux}

Actualmente, a partir de la popularizaciÃ³n de Internet, ha crecido en gran
medida la cantidad de servidores de red en todo el mundo.  Estos servidores 
deben contar con un sistema confiable, que pueda ofrecer los servicios de
correo, web, etc.  Por eso es que la gran mayorÃ­a de estos servidores
utilizan algÃºn derivado de UNIX como sistema operativo.

Dado que el sistema GNU/Linux cumple muy bien con estas caracterÃ­sticas, 
con el adicional de que se puede obtener completamente gratis, 
aÃ±o a aÃ±o ha crecido el nÃºmero de servidores que lo utilizan.

En el caso de las computadoras personales, a partir de la apariciÃ³n de mÃ¡s y
mÃ¡s aplicaciones grÃ¡ficas, de uso general en el sistema GNU/Linux, se ha
hecho posible la utilizaciÃ³n de este sistema para computadoras de escritorio.
La gran cantidad de software desarrollado en todo el mundo, permite tener muy
buena compatibilidad con otras computadoras, y tener disponibles -al mismo
tiempo- las herramientas UNIX.

\subsection{Software Libre}

A lo largo de todo este curso, siempre utilizamos Software Libre.  Por lo
general, este software lo hemos obtenido gratuitamente, sin embargo,
debemos entender que el hecho de que el software sea libre estÃ¡
relacionado {\bf con la libertad} que nos otorga a los usuarios de
utilizarlo, modificarlo y distribuirlo, {\bf no con el
precio} al cual lo podemos obtener.

Al hablar de software libre se suelen clasificar los distintos grados de
libertad a los que podemos tener acceso los usuarios.

\begin{description}
\item[Libertad Grado 0]
        El software se puede {\bf usar}.
        Es la libertad que nos otorga casi cualquier software.

\item[Libertad Grado 1]
        El software se puede {\bf modificar}.  Es decir, se puede personalizar,
        mejorar, adaptar para las necesidades particulares de un determinado
        usuario.
\item[Libertad Grado 2]
        El software se puede {\bf distribuir}.  Es decir, se puede copiar, vender,
        prestar o compartir a las personas que el usuario desee, sin tener que
        pedir permiso al autor del software.
\item[Libertad Grado 3]
        El software se puede {\bf distribuir modificado}.  Se trata de una suma de
        la 1 y la 2.  Permite que las mejoras que un usuario le haya hecho a un
        determinado software puedan compartirse con otros usuarios.
\end{description}

Para poder considerar que una determinada aplicaciÃ³n cumple con los
requisitos de software libre es necesario que estÃ©n dadas estas
cuatro libertades para {\bf cualquier} usuario.

En particular para poder tener la libertad de modificar el software,
es necesario tener acceso al cÃ³digo fuente del programa en
cuestiÃ³n, y no solamente al cÃ³digo binario (llamamos cÃ³digo
binario a aquÃ©l que es entendido por la computadora) ya que para
poder modificar correctamente el software es necesario poder acceder
al cÃ³digo fuente original. \\

Estas ideas de software libre como las conocemos hoy fueron desarrolladas y
trabajadas durante mucho tiempo por Richard Stallman y sus seguidores,
miembros de la ``Free Software Fundation'' (FundaciÃ³n del Software
Libre).

En general las ideas del software libre buscan promover la
generaciÃ³n de mejor software (a travÃ©s de la suma de los
pequeÃ±os aportes de cada persona), y colaborar para que toda la
sociedad se vea beneficiada con los avances del software. Es decir,
logramos mejorar la sociedad al tener disponibles mÃ¡s y mejores
herramientas.

Para mÃ¡s informaciÃ³n sobre el software libre pueden visitar el sitio
de internet del Proyecto GNU (http://www.gnu.org), que tiene una gran cantidad
de documentos relacionados con la filosofÃ­a del software libre.

\newpage

\section{Conceptos Generales}

\subsection{Modo GrÃ¡fico - Modo Consola}

Como ya dijimos anteriormente, GNU/Linux puede utilizar el {\it Modo
GrÃ¡fico}, si utiliza la aplicaciÃ³n XFree86.

Por otro lado, llamamos {\it Modo Consola}, al modo que es puramente texto.
Gran cantidad de los temas que se enseÃ±an en este curso se pueden probar en
modo consola, o bien en una consola grÃ¡fica, dentro del modo grÃ¡fico.

\subsection{Comenzando la sesiÃ³n}

Dado que UNIX es un sistema multiusuario, para poder comenzar a utilizarlo
debemos ingresar el usuario y password que nos identifica.  Esto lo podemos
hacer tanto en modo grÃ¡fico como en modo consola.

Muchas veces, cuando ingresemos nuestra contraseÃ±a a un sistema UNIX, no
veremos los caracteres (ni siquiera un '*').  Esto se debe a que de esta
manera es mÃ¡s difÃ­cil que un observador sepa la cantidad de caracteres que
contiene nuestra contraseÃ±a. \\

Una vez que hayamos ingresado, tendremos acceso a nuestros archivos, y podremos
ejecutar una gran cantidad de aplicaciones, segÃºn los permisos que se le
hayan dado a nuestro usuario. 

Es decir que, cada usuario que utilice el sistema tendrÃ¡ un tratamiento
distinto.  A esto nos referimos cuando decimos que todo sistema derivado de
UNIX es {\bf multiusuario}. \\

En particular, existe un usuario que es el encargado de administrar el
sistema, es el usuario que tiene acceso a los archivos de configuraciÃ³n, a
instalar y desinstalar el sistema.  Este usuario suele tener el nombre de {\it
root}, o tambiÃ©n {\it superusuario}.


\subsection{Permisos y propiedad}

En GNU/Linux los permisos sobre los programas y los archivos del sistema son
bastante mÃ¡s especÃ­ficos que en sistemas como Windows.
Existen los conceptos de {\bf propiedad} y {\bf permisos}.

Propiedad: los usuarios son propietarios de archivos.
Todos los archivos que un usuario crea son su propiedad.

Permisos: se refiere a lo que un usuario puede hacer con un determinado archivo,
sea o no el dueÃ±o de ese archivo.  Mediante los permisos, se controla quiÃ©n 
puede visualizar, editar o ejecutar archivos en el sistema.

\subsection{Consolas virtuales}

En GNU/Linux y en sistemas UNIX modernos en general, es normal que nuestra
computadora funcione como muchas terminales a un mismo tiempo.  
En un sistema UNIX tradicional, por otro lado, cada estaciÃ³n de
trabajo nos darÃ­a acceso a una Ãºnica terminal del sistema.

A esta caracterÃ­stica que nos permite tener varias terminales en una sola
computadora, la llamamos {\it consolas virtuales}.

Para cambiar de una terminal a otra, normalmente se utiliza la combinaciÃ³n de
teclas {\bf Alt-F1}, {\bf Alt-F2}, etc.  O bien, {\bf Ctrl-Alt-F1}, 
{\bf Ctrl-Alt-F2}, etc.

Dentro de una consola podemos movernos hacia arriba o hacia abajo, utilizando
la combinaciÃ³n de teclas {\bf Shift-PgUp} y {\bf Shift-PgDn}.

\subsection{Apagado del sistema}

Como en otros sistemas operativos, es importante ejecutar un comando que
cierre todas aquellas aplicaciones que estÃ©n corriendo, antes de apagar el
sistema.  En caso contrario, al reiniciar el sistema operativo se efectuarÃ¡
una verificaciÃ³n del disco rÃ­gido.

A diferencia de otros sistemas operativos, los sistemas UNIX estÃ¡n pensados
para permanecer encendidos constantemente, esto hace que los usuarios comunes
(los que no son el superusuario) no puedan apagar el sistema en forma remota.

En consecuencia, cuando solamente tenemos acceso de nivel usuario a una
computadora con un sistema UNIX, la Ãºnica manera de apagarla en forma segura
es haciendo {\bf Ctrl-Alt-Del} desde modo consola.  Una vez presionada esta
combinaciÃ³n de teclas, todos los procesos que se estÃ©n ejecutando serÃ¡n
detenidos, y la computadora se reiniciarÃ¡.

En cambio, si fuÃ©ramos el superusuario del sistema, podremos ejecutar los
comandos \verb!halt! o \verb!reboot! para apagar o reiniciar el sistema,
respectivamente.


\section{Recorrido por el sistema}

Vamos a ver algunos comandos bÃ¡sicos de todo UNIX, que nos permitirÃ¡n
familiarizarnos con el sistema.  Para poder utilizar estos comandos ya debemos
haber iniciado la sesiÃ³n.

Cuando hemos iniciado la sesiÃ³n estaremos delante de un {\it prompt}
(solicitud), que es la lÃ­nea de comandos de UNIX.  El formato de
este prompt serÃ¡ similar a: \verb!user@anteojito:~$!. \\  %$

La mayorÃ­a de estos comandos son herramientas simples, que realizan una sola
tarea.  MÃ¡s adelante aprenderemos como combinar lo que hacen dos o mÃ¡s
herramientas para lograr un resultado mÃ¡s interesante.

Algunos de estos comandos pueden recibir opciones o parÃ¡metros, que
pueden hacerlos realizar tareas diferentes.  En UNIX, casi todas las
opciones que reciba un comando estarÃ¡n precedidas por el caracter
\verb!-!, y pueden combinarse segÃºn sea necesario. \\

Es importante notar que UNIX es sensible a las mayÃºsculas y
minÃºsculas ({\it case sensitive}), de forma que si queremos
obtener la salida correcta es necesario escribir los comandos que
aquÃ­ se explican tal cual se presentan (casi siempre en
minÃºsculas).

\subsection{Comandos Sencillos}

\subsubsection{date}

Ejecutando el comando \verb!date! obtendremos la fecha y
la hora actual. TambiÃ©n es el comando que se usa para cambiar la
fecha de la mÃ¡quina.

\subsubsection{who}
El comando \verb!who! nos permite ver los usuarios que estÃ¡n
utilizando el sistema, incluyendo la fecha en la que se conectaron al
sistema.

AdemÃ¡s, una versiÃ³n alternativa (\verb!who am i!) nos
muestra Ãºnicamente nuestra conexiÃ³n.

\subsubsection{uptime}

Podemos ver cuÃ¡nto tiempo hace que se ha iniciado el sistema de
nuestra computadora ejecutando el comando \verb!uptime!.  TambiÃ©n
obtendremos alguna informaciÃ³n adicional, como la cantidad de
usuarios que estÃ¡n utilizando el sistema, o la carga promedio que
tiene el procesador.

\subsubsection{clear}

El comando \verb!clear! sirve para limpiar la pantalla. Es
equivalente al \verb!cls! de DOS.

\subsubsection{echo}

\verb!echo! es un comando muy sencillo.  Lo que hace es
repetir todo lo que recibe por lÃ­nea de comandos.  Si ejecutamos:
\verb!echo Hola! obtendremos la salida \verb!Hola!.

A pesar de parecer inÃºtil, este comando nos serÃ¡ de bastante
utilidad cuando aprendamos mÃ¡s sobre el intÃ©rprete de comandos del
sistema.

\subsection{Comandos relacionados con archivos y directorios}

\subsubsection{pwd}

El comando \verb!pwd! es muy sencillo, nos
muestra la ruta de directorios en la que estamos situados en este
momento. Por ejemplo, {\bf /home/user}.

\subsubsection{ls}
Para listar los archivos dentro de un determinado directorio
utilizaremos el comando \verb!ls!. El equivalente en DOS es 'dir'.

Si ejecutamos \verb!ls! sin ninguna opciÃ³n, nos listarÃ¡ los
archivos del directorio actual.  Si, en cambio, ejecutamos
\verb!ls directorio!, nos listarÃ¡ los archivos de ese
directorio.

Puede recibir varias opciones:

\begin{itemize}
\item \verb!-l!: muestra mucha mÃ¡s informaciÃ³n sobre los archivos,
como el usuario y el grupo al que pertenece, el tamaÃ±o, los
permisos, etc.
\item \verb!-a!: muestra todos los archivos, incluyendo los ocultos.
\item \verb!-t!: ordena los archivos por fecha de modificaciÃ³n.
\end{itemize}

Estas opciones pueden combinarse, utilizando un solo signo '-', por ejemplo:
\verb!ls -lat!.

\subsubsection{touch}

El comando \verb!touch archivo! puede tener dos
consecuencias: si \verb!archivo! no existe aÃºn, lo crea con tamaÃ±o
0 y como propiedad de nuestro usuario.  Por otro lado, si
\verb!archivo! ya existe, actualiza la fecha de modificaciÃ³n.

\subsubsection{cp}

El comando \verb!cp! es el que se utiliza para copiar archivos.

Si escribimos \verb!cp viejo nuevo!, copiaremos el archivo
\verb!viejo! con el nombre \verb!nuevo!.  Es decir, el archivo
origen se escribe primero y a continuaciÃ³n el archivo que se va a
crear. Una vez hecha la copia, tendremos dos archivos diferentes, con
el mismo contenido.

Por otro lado, tambiÃ©n podemos ejecutar 
\verb!cp archivo1 archivo2 directorio!, 
de forma que los archivos \verb!archivo1! y
\verb!archivo2! se copiarÃ¡n dentro de \verb!directorio!.

\subsubsection{mv}

Muy similar a \verb!cp!, el comando \verb!mv! es el que se utiliza para mover
archivos de un lugar a otro, o para cambiarle el nombre a un archivo.  Si
ejecutamos, \verb!mv viejo nuevo!, el archivo \verb!viejo! habrÃ¡ pasado a
llamarse \verb!nuevo!.

Por otro lado, si ejecutamos \verb!mv archivo1 archivo2 directorio!, los
archivos \verb!archivo1! y \verb!archivo2! se moverÃ¡n dentro de
\verb!directorio!.

\subsubsection{rm}

Para borrar archivos utilizamos el comando \verb!rm!.  Hay que usarlo
cuidadosamente, porque una vez que los archivos han sido borrados, no pueden
recuperarse {\bf de ninguna forma}.

Si deseamos que \verb!rm! nos pregunte si queremos borrar o no un archivo,
debemos utilizar la opciÃ³n \verb!-i!, mientras que si deseamos que no nos
pregunte utilizamos la opciÃ³n \verb!-f!.  DependerÃ¡ de la configuraciÃ³n
del sistema cual de estas dos opciones es la que estÃ¡ seleccionada por
omisiÃ³n.

\subsubsection{mkdir}

Utilizamos el comando \verb!mkdir directorio! para crear directorios.  Pueden
utilizarse rutas absolutas o relativas.  Es decir que si queremos crear el
directorio \verb!/home/user/temp!, y estamos situados dentro del directorio
\verb!/home/user!, podremos ejecutar \verb!mkdir temp! o
\verb!mkdir /home/user/temp! indistintamente.

\subsubsection{rmdir}

Para borrar directorios utilizamos el comando \verb!rmdir directorio!.  
Solamente funcionarÃ¡ si el directorio estÃ¡ vacÃ­o.
En caso contrario, habrÃ¡ que borrar primero los archivos, para luego borrar 
el directorio.

\subsubsection{cd}

El comando \verb!cd! nos permite cambiar de directorio, igual que en DOS. \\

Por ejemplo, \verb!cd /! nos lleva al directorio raÃ­z, que es de donde
surgen todos los directorios del sistema.

Para cambiar a otro directorio dentro del Ã¡rbol, podemos utilizar 
\verb!cd usr!, o \verb!cd /home/user!. MÃ¡s adelante veremos 
cÃ³mo se organiza el
Ã¡rbol de directorios, y quÃ© hay en cada uno. \\

Utilizado sin ningÃºn otro parÃ¡metro, \verb!cd! nos lleva al directorio
personal del usuario ({\it home}). Otra manera de ir al directorio personal es
utilizar \verb!cd ~!, ya que el sÃ­mbolo \verb!~! identifica al directorio de
cada usuario.\\

Para cambiar al directorio padre del directorio actual se utiliza \verb!cd ..!
(no olvidar el espacio).  Mientras que para volver al directorio en el que nos
encontrÃ¡bamos antes de ejecutar el Ãºltimo \verb!cd!, podemos ejecutar
\verb!cd -!.

\subsubsection{file}

En UNIX los archivos no se identifican por su extensiÃ³n, como en DOS.  Se les
puede poner una extensiÃ³n, pero es de adorno.

El comando \verb!file! nos permite tener una idea del contenido de un archivo.
Al ejecutar \verb!file archivo!, inspecciona partes del archivo para darse cuenta
quÃ© clase de archivo es.  Puede decirnos que se trata de un archivo de texto,
un directorio, una imagen, etc.

\subsubsection{du}

El comando \verb!du!, {\it Disk Usage}, nos muestra el espacio que ocupan
todos los directorios a partir del directorio actual.  El nÃºmero de la primera
columna es el espacio ocupado por el directorio y estÃ¡ expresado en kb. 

\begin{itemize}
\item \verb!du -s! nos muestra Ãºnicamente el total.

\item \verb!du -a! muestra lo que ocupan los archivos, ademÃ¡s de los directorios.

\item \verb!du -h! hace el listado, indicando la unidad (human readable).

\item \verb!du archivo! nos dice cuÃ¡nto ocupa el archivo.
\end{itemize}

\subsubsection{df}

El comando \verb!df!, {\it Disk Free}, nos muestra quÃ© tan ocupados estÃ¡n los
discos del sistema. El parÃ¡metro \verb!-h!, al igual que en el caso del
comando \verb!du!, nos muestra las unidades en que se miden los numeros
presentados.

\subsubsection{find}

El comando \verb!find! permite encontrar archivos, utilizando diversas
tÃ©cnicas.  En principio, si se le pasa como parÃ¡metro Ãºnicamente una
determinada ruta, por ejemplo \verb!find /home/user!, el comando buscarÃ¡
todos los archivos y directorios que se encuentren a partir de esa ruta.

Utilizando algunos otros parÃ¡metros es posible buscar los archivos por
diversos criterios.

\begin{itemize}

\item \verb!find . -name "hola.txt"! encuentra todos los archivos llamados
\verb!hola.txt! que se encuentren a partir del directorio actual.  Las
comillas no son obligatorias, pero son recomendables si se quieren usar
opciones mÃ¡s complejas (por ejemplo, utilizando meta-caracteres de shell,
que se explican en la secciÃ³n \ref{metacaracteres}).

\item \verb!find . -size 50k! busca los archivos que ocupan 50 kilobytes a
partir del directorio actual. Si se utiliza \verb!find . -size 20c!,
buscarÃ¡ los archivos que ocupen 20 bytes.  Y si se utiliza
\verb!find . -size 5b!, buscarÃ¡ los archivos que ocupen 5 bloques de 512
bytes cada uno.

\item \verb!find /home/user -empty! busca todos los archivos que se
encuentran vacÃ­os, a partir del directorio \verb!/home/user!.

\end{itemize}

Es posible, ademÃ¡s, utilizar opciones adicionales para la bÃºsqueda, que
indiquen la profundidad de la bÃºsqueda, que agreguen otros criterios
adicionales a los explicados, o que indiquen una acciÃ³n a llevar a cabo una vez
encontrados los archivos.

\subsubsection{locate}

Otro comando que nos permite buscar archivos es \verb!locate!. Las busquedas de
\verb!locate! nos sirven para encontrar archivos en cualquier parte del
sistema, por ejemplo \verb!locate bash! nos va a mostrar todos los archivos y
directorios del sistema que en su nombre contienen la palabra {\bf bash}.

Las busquedas de \verb!locate! son mucho mÃ¡s rÃ¡pidas que las de \verb!find!,
esto se debe a que utiliza una base de datos que contiene los nombres de los
archivos de todo el sistema. Esta base de datos no se actualiza
constantemente, por lo que \verb!locate! no encontrarÃ¡ los archivos reciÃ©n
agregados al sistema e incluirÃ¡ los recientemente removidos hasta que esta
base de actualice.

Para actualizar esta base de datos debemos ejecutar \verb!updatedb!, como
superusuario.  En las mÃ¡quinas que estÃ¡n prendidas constantemente, este
programa se ejecuta una vez al dÃ­a, durante la madrugada, de manera que la
base de datos permanece acualizada.

\subsubsection{cat}

Ejecutando \verb!cat archivo! podremos ver el contenido de
\verb!archivo!.  Este comando puede recibir una serie de archivos, y
el resultado serÃ¡ que nos mostrarÃ¡ un archivo a continuaciÃ³n del
otro.

Un caso especial se produce cuando ejecutamos \verb!cat! sin ningÃºn nombre
de archivo.  En este caso, el comando esperarÃ¡ a que nosotros le demos una
entrada, y la irÃ¡ reproduciendo lÃ­nea por lÃ­nea.  Hasta que presionemos
la combinaciÃ³n {\bf Ctrl-d}, que indica que la entrada ha terminado.

\subsubsection{od}

El comando \verb!od! {\it Octal Dump}, nos permite ver byte a byte el
contenido de un archivo.  La primera columna es la direcciÃ³n de cada lÃ­nea
que vemos. Utilizando las distintas opciones, podemos
visualizarlo en varios formatos: 

\begin{itemize}
\item \verb!od archivo! nos muestra el contenido del archivo expresado en
nÃºmeros octales, generalmente tomados de a dos bytes.
\item \verb!od -b archivo! nos muestra el contenido, en nÃºmeros octales, byte a byte.
\item \verb!od -c archivo! nos muestra los caracteres que forman el archivo,
uno por uno.
\item \verb!od -cb archivo! nos muestra los caracteres, y debajo de cada
caracter el nÃºmero octal del byte.
\item \verb!od -h archivo! nos muestra el contenido, en nÃºmeros hexadecimales,
tomados de a dos bytes.
\end{itemize}

Las nuevas versiones de \verb!od! soportan muchos mÃ¡s formatos, utilizando la
opciÃ³n \verb! -t formato!.


\subsubsection{wc}

El comando \verb!wc archivo!, se utiliza para contar la cantidad de lÃ­neas,
palabras y letras que tiene un archivo.

\subsubsection{less}

El comando \verb!less! permite paginar la salida de otros comandos, o bien, el
contenido de algÃºn archivo.

Si ejecutamos \verb!less archivo!, veremos la primera pÃ¡gina del archivo.
Si este archivo es lo suficientemente largo, podremos movernos hacia abajo y
hacia arriba utilizando PageUp, PageDown, Home, End, Enter, los cursores, la
barra espaciadora, etc.

TambiÃ©n podemos realizar bÃºsquedas dentro del archivo, para ello
utilizamos la barra \verb!/!, seguida del patrÃ³n que queremos
buscar.  Por ejemplo, si tipeamos \verb!/consola!, nos mostrarÃ¡ la primera
ocurrencia del patrÃ³n \verb!consola!.  Para ver la siguiente ocurrencia,
utilizamos \verb!n!, y para ver la ocurrencia anterior \verb!N!.

Para salir, utilizamos \verb!q!.

\subsection{Comandos relacionados con procesos}

Cada aplicaciÃ³n que se ejecuta dentro de un sistema UNIX es un proceso.
Algunos procesos estÃ¡n ejecutÃ¡ndose sin que nosotros lo sepamos.  Otros
procesos comienzan a ejecutarse cuando nosotros se lo indicamos.  

Cada proceso que se ejecuta dentro de nuestra computadora tiene un nÃºmero
que lo identifica, llamado {\it Process ID} (PID). Este nÃºmero serÃ¡ el que
deberemos utilizar para referirnos a ese proceso con otros comandos.

Vemos a continuaciÃ³n los comandos bÃ¡sicos para manejar procesos dentro de
los sistemas UNIX.

\subsubsection{top}

El comando \verb!top! nos muestra algunos de los procesos que se estÃ¡n
ejecutando, ordenados por el tiempo de procesador de la computadora que
consumen.  Muestra algunos datos adicionales de cada proceso, por ejemplo, en
la primera columna, podemos observar el PID de cada uno.

AdemÃ¡s, muestra otros datos acerca del uso que se le esta dando a la
mÃ¡quina.

Para salir: q.

\subsubsection{ps}

El comando \verb!ps! nos muestra la lista de procesos que se estÃ¡n
ejecutando en la computadora.  En particular, es interesante ver la salida de
\verb!ps ax!, que nos muestra todos los procesos, tanto los de nuestro usuario
como los de otros, e incluso los procesos que no tienen usuario.

La primera columna de la salida de \verb!ps! tambiÃ©n contiene 
el PID del proceso.

\subsubsection{Ctrl-z}

La combinaciÃ³n de teclas {\bf Ctrl-z} sirve para suspender una tarea dentro
de su ejecuciÃ³n.

Por ejemplo, si estamos ejecutando el proceso \verb!top! y presionamos {\bf
Ctrl-z}, se suspenderÃ¡ la ejecuciÃ³n de \verb!top! y volveremos a obtener
la lÃ­nea de comandos.  Antes de devolvernos la lÃ­nea de comandos, nos
indicarÃ¡ cuÃ¡l es el nÃºmero de trabajo del proceso que hemos suspendido.

Podemos iniciar varias tareas distintas, y luego suspenderlas.  De forma que
el nÃºmero de trabajo de las tareas suspendidas se va incrementando.

\subsubsection{bg - fg}

El comando \verb!bg! permite que el proceso que se halle suspendido, continÃºe
ejecutÃ¡ndose en {\it background} (de fondo).  Mientras que el comando
\verb!fg! permite que un proceso suspendido pase a {\it foreground} (a la
pantalla principal). Por ejemplo, \verb!find /usr -name nethack! busca dentro
de /usr (grande) un archivo llamado nethack, esto puede tomar una considerable
cantidad de tiempo, apretando \verb!Ctrl-z! y luego ejecutando \verb!bg!
conseguimos que se siga ejecutando de ``fondo'', mientras nosotros podemos
seguir usando la consola. Cabe aclarar que cuando find encuentre algo lo
imprimira en la pantalla.

\subsubsection{jobs}

Para poder ver quÃ© comandos se estÃ¡n ejecutando en background y cuÃ¡les
han sido suspendidos (o detenidos), podemos utilizar el comando \verb!jobs!.

La lista que nos muestra este comando incluye el nÃºmero de trabajo, que no
es el mismo que el PID, y podemos utilizar este identificador para decidir
cuÃ¡l de las tareas pasar a foreground o background.

Por ejemplo: \verb!fg 1! pasa a foreground el trabajo nÃºmero 1. Mientras
que \verb!bg 3! pasa a background el trabajo nÃºmero 3.

\subsubsection{kill}

Este comando nos sirve para interrumpir la ejecuciÃ³n de un determinado
proceso.  El comando envÃ­a una seÃ±al al proceso por la cual (normalmente)
se cierra.

Podemos ejecutarlo teniendo en cuenta el PID del proceso. Por ejemplo:
\verb!kill 1234!, matarÃ¡ el proceso 1234.  O bien, teniendo en cuenta el
nÃºmero de trabajo.  En ese caso: \verb!kill %2!, detendrÃ¡ el trabajo
nÃºmero 2.

\subsubsection{Ctrl-c}

Cuando una aplicaciÃ³n se estÃ¡ ejecutando en foreground, y deseamos
detenerla, podemos utilizar la combinaciÃ³n de teclas {\bf Ctrl-c}.

El uso de esta combinaciÃ³n es equivalente a ejecutar el comando \verb!kill!
con el nÃºmero de proceso de la aplicaciÃ³n que estamos utilizando.

\subsection{Obteniendo mÃ¡s informaciÃ³n}

En GNU/Linux existen muchÃ­simos documentos de ayuda, manuales y HOWTOs, que
estÃ¡n pensados para que cualquier persona pueda encontrar informaciÃ³n
sobre lo que estÃ¡ buscando.

\subsubsection{man}

Un comando muy importante es \verb!man!.  Este comando nos mostrarÃ¡ las hojas
del manual del programa que estamos queriendo buscar.

Por ejemplo, \verb!man date! nos mostrarÃ¡ el manual del comando \verb!date!,
que ya sabemos que sirve para ver y configurar la fecha, aquÃ­ estÃ¡
explicado cÃ³mo utilizarlo.

Podemos movernos dentro de las pÃ¡ginas de los manuales utilizando la barra
espaciadora, Enter, los cursores y el mismo sistema de bÃºsqueda que
utilizamos en \verb!less!.  Para salir, utilizamos \verb!q!.

\subsubsection{info}

Un comando muy similar a \verb!man!, es el comando \verb!info!.  Las pÃ¡ginas
que nos muestra este comando suelen tener una mayor cantidad de informaciÃ³n
acerca de la aplicaciÃ³n sobre la cual estamos consultando.

Por ejemplo \verb!info sh-utils!, contiene informaciÃ³n detallada sobre
algunas de las utilidades del intÃ©rprete de comandos ({\it shell}), que se
verÃ¡ mÃ¡s adelante.

\subsubsection{help}

Algunos comandos (como \verb!fg!), son parte interna del intÃ©rprete de
comandos, y por esta razÃ³n no tienen una pÃ¡gina del manual que los
explique.

Para saber de quÃ© manera utilizar estos comandos, usamos \verb!help!.  La
ayuda que nos da este comando es mÃ¡s sintÃ©tica que la de \verb!man!.

Por ejemplo \verb!help jobs!, nos informarÃ¡ sobre el uso del comando
\verb!jobs! visto anteriormente.

\subsubsection{Archivos con informaciÃ³n}

Dentro del directorio \verb!/usr/share/doc!, encontramos una gran cantidad de
documentos que tratan las distintas aplicaciones que tenemos instaladas en
nuestro sistema.

En particular, el directorio \verb!/usr/share/doc/HOWTO!, contiene artÃ­culos
sobre cÃ³mo hacer determinadas cosas dentro de nuestro sistema.

\newpage

\section{Shell}

El shell es el intÃ©rprete de comandos. En DOS normalmente el shell es el
command.com, en UNIX existen muchos shell usados habitualmente. 

\begin{description}
\item[sh] Desde la sÃ©ptima ediciÃ³n de UNIX el shell por excelencia es
el {\bf sh}.  Fue escrito por Steven Bourne, y es por eso que se lo suele
llamar {\it Bourne Shell}.  EstÃ¡ disponible en todas las versiones de UNIX y
es lo suficientemente bÃ¡sico como para que funcione en todas las
plataformas.

\item[csh] Un shell un poco mejor con respecto al {\bf sh} es el {\bf csh},
que fue escrito por Bill Joy, y debe su nombre al lenguaje de programaciÃ³n
C.  Al hacer scripts en este shell puede utilizarse una sintaxis similar a la
de C.

\item[ksh] Otro shell, que como ventaja maneja un historial de comandos,
es el {\bf ksh} (korn shell).  EstÃ¡ basado en {\bf sh}, con algunos
agregados muy bÃ¡sicos para hacerlo mÃ¡s amigable.

\item[bash] Uno de los shell mÃ¡s avanzados, muy popular en la comunidad
GNU/Linux es el {\bf bash}.  El nombre significa {\it Bourne Again Shell}.
Tiene licencia GNU y se suele incluir como 
shell predeterminado en las distribuciones.

Ofrece las mismas capacidades que {\bf csh}, pero incluye funciones avanzadas,
tanto para el usuario como para el programador.  

En particular, podremos acceder a un historial de los comandos ejecutados, que
se conserva incluso al pasar de una sesiÃ³n a otra, utilizando los cursores.  

AdemÃ¡s, completa los nombres de comandos y archivos automÃ¡ticamente, al
presionar la tecla TAB.
\end{description}

Hay muchas otras versiones de shell ademÃ¡s de Ã©stas.  Pero el estilo general
de todos es muy similar.  Lo que estudiemos en este curso serÃ¡ compatible con
la mayorÃ­a de ellos.

\subsection{Meta-caracteres}
\label{metacaracteres}

AdemÃ¡s de ejecutar los comandos que nosotros le indicamos, el shell interpreta
ciertos caracteres especiales, a estos caracteres los llamamos
me\-ta\-ca\-rac\-te\-res.

Cuando nosotros utilizamos algÃºn meta-caracter, los comandos no lo reciben,
sino que el shell lo reemplaza por lo que corresponda, y le pasa al comando
ejecutado el resultado de ese reemplazo.

Eso es lo que entendemos por {\it interpretar}: reemplazar el caracter por otro
caracter o por una cadena de caracteres, segÃºn corresponda.

\subsubsection{Meta-caracteres relacionados con archivos}

\begin{tabular}{lp{12cm}}
\verb!*! &amp; Cuando el shell encuentra un \verb!*!, lo reemplaza por una lista de
los archivos que concuerdan con la expresiÃ³n indicada.  

Por ejemplo: \verb!echo *!
nos mostrarÃ¡ todos los archivos del directorio.  \verb!echo a*! nos mostrarÃ¡
todos los archivos del directorio que comiencen con a.  \verb!echo *o! nos
mostrarÃ¡ todos los archivos que terminen con o. \verb!echo /usr/local/*! 
nos mostrarÃ¡ todos los archivos que estÃ©n en ese directorio. 

En el caso de
que no hubiera ningÃºn archivo que concuerde con la expresiÃ³n, generalmente,
nos mostrarÃ¡ la expresiÃ³n que hayamos escrito.

\\
\verb!?! &amp; Al encontrar un \verb!?! el shell lo reemplaza por cualquier otro
caracter.  Es decir que la expresiÃ³n que escribamos se reemplazarÃ¡ por todos
los archivos que en esa posiciÃ³n tengan cualquier caracter, y en el resto de
la cadena tengan lo que hemos escrito.  

Por ejemplo: \verb!echo ?ola! nos
podrÃ­a mostrar archivos como \verb!hola!, \verb!sola!, \verb!Pola!. 
\verb!echo a??a!, podrÃ­a mostrar \verb!allÃ¡!, \verb!arca!, \verb!Asia!.  

Al igual que con el \verb!*!, si ningÃºn archivo concuerda con el patrÃ³n,
generalmente, nos mostrarÃ¡ la misma expresiÃ³n que hemos escrito. 

\\
\verb![ ]! &amp; Encerrados por los corchetes, podemos escribir un rango de
caracteres con los cuales queremos que el shell concuerde. 

Por ejemplo, 
\verb!ls [af]*! nos mostrarÃ¡ todos los archivos que comienzan con a o con f.

Podemos ademÃ¡s especificar un rango de caracteres, con un guiÃ³n en el
medio.  Por ejemplo, \verb!a-z! (letras minÃºsculas), \verb!0-9! (nÃºmeros),
etc. y combinarlos con caracteres individuales siempre que no sea ambigua la
interpretaciÃ³n. (Considerar la concordancia con el caracter -). 

Por ejemplo, podemos querer sÃ³lo los archivos que comienzan con nÃºmeros 
seguidos de un -, en ese caso escribirÃ­amos \verb!ls [0-9]-*! o 
\verb!ls [0-9][0-9]-*!, si comienzan con dos nÃºmeros seguidos de un -.

\\
\verb![^ ]! &amp; Cuando al comienzo de la cadena que estÃ¡ encerrada por los
corchetes encontramos el caracter \verb!^!, estamos indicando que debe
concordar los caracteres que no se encuentran en el rango.  

Por ejemplo, \verb!ls [^0-9]*!, nos listarÃ¡ todos los archivos que no
comiencen con un nÃºmero.

\end{tabular}

\subsubsection{Meta-caracteres relacionados con comandos}

Ejecutar un comando es tan sencillo como escribir el comando y apretar ENTER.
Sin embargo, utilizando algunos de los meta-caracteres de shell podemos combinar
los comandos entre sÃ­, y lograr resultados mucho mÃ¡s importantes.

\begin{description}
\item[;] El \verb!;! es un separador de comandos, nos permite ejecutar un
comando a continuaciÃ³n de otro, equivalente a lo que sucederÃ­a si
ejecutÃ¡ramos primero uno, y al terminar ejecutÃ¡ramos el siguiente.  

Es decir si escribimos \verb!ls; echo Hola! veremos la salida del \verb!echo! 
a continuaciÃ³n de la del \verb!ls!.

\item[( )] Los parÃ©ntesis sirven para encerrar grupos de comandos, y
tratarlos como si fueran uno solo.

\item[\&amp;] El \verb!&amp;! manda el comando a background, esto quiere decir, que nos
devuelve la lÃ­nea de comandos inmediatamente despuÃ©s de apretar Enter,
mientras el comando sigue ejecutÃ¡ndose en segundo plano. 

La ejecuciÃ³n de tareas en segundo plano ya se ha estudiado anteriormente,
cuando se vieron los comandos relacionados con procesos.  Este meta-caracter
funciona de manera equivalente, y sus resultados pueden corroborarse
utilizando el comando \verb!jobs!.

Para ver un ejemplo, vamos a usar un nuevo comando, \verb!sleep!, (un comando
simple que espera una determinada cantidad de segundos). Por ejemplo
\verb!sleep 5!, espera 5 segundos antes de devolvernos la lÃ­nea de comandos.

Ahora, utilizando \verb!&amp;!: \verb!(sleep 20; echo Hola) &amp;!. Al
escribirlo nos mostrarÃ¡ el PID del comando que estamos ejecutando, y nos
devolverÃ¡ el shell; 20 segundos despuÃ©s, veremos aparecer ``Hola'' en
nuestra lÃ­nea de comandos.  

Antes de que termine de ejecutarse, podemos ejecutar \verb!jobs! y observar
que el proceso se estÃ¡ ejecutando, o bien \verb!ps! y observar que el
comando en ejecuciÃ³n es {\bf sleep}.

{\bf Ejercicio}: 
hacer un comando equivalente que nos avise que ya pasaron los cinco
minutos necesarios para que hierva una pava de agua. \\

AdemÃ¡s, el \verb!&amp;! nos puede servir para separar comandos: cada vez que lo
utilizamos para separar comandos, mandarÃ¡ al comando que estÃ© a su izquierda
a background.

\end{description}

\subsubsection{Otros meta-caracteres}

\begin{description}

\item['...'] Al encontrar una cadena encerrada entre ' ', el shell tomarÃ¡ el
  contenido de la cadena literalmente, es decir, sin interpretar los
  meta-caracteres contenidos en ella.

  Por ejemplo, {\bf echo '* ?* [A-Z-]*'} nos mostrarÃ¡ * ?* [A-Z-]*.

  Notar que si no cerramos las comillas y apretamos ENTER, el shell nos
  mostrarÃ¡ una lÃ­nea en blanco esperando que sigamos ingresando nuestro
  comando, hasta que cerremos las comillas.

\item[$\backslash$] Utilizamos una $\backslash$ para escapar el siguiente
  caracter.  Escapar significa que el shell no lo interpretarÃ¡ como un
  meta-caracter.

  Por ejemplo \verb!echo \*! nos mostrarÃ¡ un \verb!*!.

\item[\#] El \verb!#! es el seÃ±alador de comentario. Si el shell encuentra un
  \# al comienzo de una palabra, descartarÃ¡ todos los caracteres hasta en
  final de lÃ­nea. Por ejemplo, \verb!echo 3.1416 # Pi con un error de 0.0001!
  nos mostrarÃ¡ Ãºnicamente \verb!3.1416!.

\end{description}

\subsubsection{Entrada y Salida}

UNIX tiene un extenso manejo de entrada y salida, es una de las
caracterÃ­sticas principales que nos permite combinar pequeÃ±as herramientas
para lograr resultados mÃ¡s complejos.

La mayorÃ­a de los comandos UNIX que nosotros utilizamos tienen una entrada
estÃ¡ndar, una salida estÃ¡ndar y una salida para errores estÃ¡ndar.  Las
denominamos {\bf stdin}, {\bf stdout} y {\bf stderr} respectivamente.

La entrada estÃ¡ndar por omisiÃ³n es el teclado, mientras que la salida
estÃ¡ndar y la salida de errores son, por omisiÃ³n, la pantalla.

Un comando genÃ©rico, lee datos de la entrada estÃ¡ndar, los procesa de
alguna manera, y luego emite el resultado por la salida estÃ¡ndar.  En el caso
de que durante el proceso hubiera algÃºn error, emitirÃ¡ una aviso de ese
error por la salida de errores.

El Shell se encarga de relacionar estos tres, lo cual no impide que un
determinado programa maneje su entrada y su salida de una manera diferente.

\begin{description}

\item[$&gt;$] 
El caracter \verb!&gt;! nos permite direccionar la salida estÃ¡ndar de un
comando a un archivo.  De manera que \verb!ps ax &gt; procesos! 
guardarÃ¡ en el
archivo \verb!procesos! la salida del ps.
\item[$&lt;$]
El caracter \verb!&lt;! nos permite direccionar la entrada estÃ¡ndar de un
comando desde un archivo.  Por ejemplo, el comando \verb!mail! nos sirve
para mandar mensajes a otros usuarios, si escribimos 
\verb!mail user &lt; archivo!
mandarÃ¡ un mensaje con el contenido del archivo al usuario user.
\item[$&gt;&gt;$] 
Usar un \verb!&gt;&gt;! en lugar de un \verb!&gt;! nos permite direccionar la salida
estÃ¡ndar a un archivo, sin sobreescribirlo, sino que le agrega los datos que
nosotros queramos al final.  Si ahora hacemos \verb!ps ax &gt;&gt; procesos! 
tendremos el listado de procesos dos veces en un mismo archivo.
\item[2$&gt;$] Utilizar \verb!2&gt;! nos permite redirigir la salida de errores a 
un archivo. Por ejemplo, si ejecutamos \verb!ls archivo-feo 2&gt; test!, 
el error del \verb!ls!,
indicÃ¡ndonos que el archivo-feo no existe se almacenarÃ¡ en test.
\item[$|$] 
Para relacionar la salida estÃ¡ndar de un comando, con la entrada
estÃ¡ndar de otro comando, 
utilizamos el caracter \verb!|!.  Por ejemplo, podemos
relacionar la salida de \verb!ls! con la entrada de \verb!wc!.  Haciendo 
\verb!ls | wc!, la salida de este comando serÃ¡ la cantidad de lÃ­neas, 
palabras y caracteres que produjo \verb!ls!.

Este comando recibe el nombre de {\it pipe}, que en inglÃ©s significa
caÃ±erÃ­a o tuberÃ­a.  Es decir que es un comando que {\it entuba} la
salida de un comando con la entrada de otro.

\end{description}

Es interesante observar lo que sucede cuando hacemos: 
\verb!ls &gt; nuevo-archivo!,
esto es, el archivo nuevo aparece dentro del listado que hace ls.  Esto se debe
a que el shell, al hacer la relaciÃ³n entre el archivo y el comando, crea el
archivo, y luego llama al \verb!ls!.

AdemÃ¡s es necesario tener en cuenta que un comando no puede utilizar como
entrada y salida un mismo archivo.  Por ejemplo, al ejecutar
\verb!cat archivo &gt; archivo!, 
el intÃ©rprete de comandos nos indicarÃ¡ que esto no es posible.

\subsubsection{Ejercicios}

\begin{enumerate}
\item Explicar en quÃ© se diferencian \verb!ls *! y \verb!echo *!.
\item Explicar en quÃ© se diferencian \verb!ls /! y \verb!echo /!.
\item Crear un archivo que contenga la cantidad de archivos en un directorio.
\item Crear dos archivos: \verb!a.txt!, que contenga \verb!hola!, y 
\verb!b.txt!, 
que contenga \verb!chau!.  Luego concatenarlos en un archivo \verb!ab.txt!.
\end{enumerate}

\section{Manejo de Archivos}

Una de las caracterÃ­sticas de UNIX es que todo es un archivo.  Esto no es una
simplificaciÃ³n, el sistema representa los dispositivos (disco rÃ­gido, placa
de sonido, CDs, disqueteras, algunas conexiones de red, etc) 
que estÃ¡n conectados a Ã©l como archivos. 

Estos archivos estÃ¡n todos ubicados a partir del directorio raÃ­z, a partir
del cual se abre un Ã¡rbol de directorios.  Al directorio raÃ­z se lo
identifica como {\bf /}.  Si hacemos \verb!ls /! veremos los directorios que se
abren a partir del raÃ­z.

Una de las ventajas del manejo de archivos de UNIX es que los usuarios no
necesitan saber dÃ³nde estÃ¡ cada directorio.  Cuando hacemos \verb!ls /!
puede suceder que algunos directorios estÃ©n en el disco rÃ­gido de la PC,
otros estÃ©n en un servidor de la red, otros en algÃºn otro servidor, y
nosotros no nos enteraremos.

Identificamos con el nombre de {\bf file-system} a una estructura jerÃ¡rquica
de directorios y archivos.  Es decir, una determinada colecciÃ³n de archivos.
En un solo sistema UNIX pueden estar {\it montados} varios file-systems
diferentes.  Esto es, un solo sistema UNIX puede agrupar los archivos que
estÃ¡n almacenados en distintas particiones de un disco rÃ­gido, en una
disquetera, en un CD, etc.

El Ã¡rbol de directorios que vemos a partir del directorio raÃ­z, es la forma
en la que organizamos los archivos, no necesariamente el lugar donde los
archivos estÃ¡n ubicados fÃ­sicamente.

\subsection{Montar y desmontar file-systems}

Utilizando el comando \verb!mount! veremos los file-systems que tengamos
montados.  La salida de este comando nos lista: la identificaciÃ³n del
file-system, el lugar en el Ã¡rbol de directorios en el que estÃ¡ montado y el
tipo de file-system que constituye.  AdemÃ¡s, entre parÃ©ntesis, podemos ver
los flags con los que se ha montado.

Cuando queremos leer de un diskette, deberemos montarlo, ya que el diskette
constituye una nueva estructura de archivos.  Podremos montar diskettes que
estÃ©n grabados en distintos formatos, por ejemplo msdos, ext2, etc.

Para montar el diskette utilizaremos \verb!mount /floppy!, ya que /floppy es el
directorio en el que estÃ¡ configurado que se debe montar el dispositivo de la
disquetera, como un tipo de file-system automÃ¡tico, es decir que detecta
automÃ¡ticamente quÃ© tipo de filesystem se tiene.

Es necesario desmontar el diskette antes de sacarlo, ya que -si no lo hacemos-
el sistema puede no
haber terminado de actualizar los cambios hechos al file-system del diskette.
Para desmontarlo utilizaremos el comando: \verb!umount /floppy!. \\

Otro comando relacionado con los file-systems que se encuentran montados en
el sistema es \verb!df!.  Este comando nos muestra el espacio que estÃ¡
siendo utilizado y el que todavÃ­a estÃ¡ libre, en los file-systems que se
encuentren montados.

\subsection{Ãrbol de directorios}

Existen diferentes maneras de ordenar la informaciÃ³n dentro de los
directorios.  Veremos un orden bÃ¡sico que la mayorÃ­a de las distribuciones
utilizan.

\begin{description}

\item[/bin] contiene los archivos ejecutables bÃ¡sicos del sistema.  Muchos de
estos comandos ya los usamos o los vamos a usar en el futuro.

En este directorio, por ejemplo, encontramos algunos de los comandos de
shell que nombramos.

\item[/dev] contiene los archivos que representan a dispositivos.  Los archivos
que se encuentran en este directorio estÃ¡n relacionados con perifÃ©ricos de
la mÃ¡quina, por ejemplo: /dev/fd0 es el archivo que representa la primera
disquetera, /dev/hda representa al primer disco rÃ­gido IDE, /dev/hda1 
representa la primera particiÃ³n del primer disco rÃ­gido IDE, /dev/tty
representa la consola actual que se estÃ¡ usando.  AsÃ­: 
\verb!echo hola &gt; /dev/tty! nos mostrarÃ¡ la misma salida que 
un simple \verb!echo hola!.

Estas identificaciones corresponden al sistema de archivos utilizado por las
distribuciones de GNU/Linux.  En otros sistemas UNIX (como BSD, Solaris, etc).
Las identificaciones serÃ¡n distintas, pero las podremos encontrar en el mismo
directorio /dev.

Un dispositivo curioso es /dev/null.  Se trata de un dispositivo que borra todo
aquello que se mueva a Ã©l, como un agujero negro.  Otro dispositivo interesante
es /dev/random, que nos muestra ``basura random'', es decir cualquier tipo de
caracteres, generados al azar segÃºn los procesos que se estÃ©n ejecutando en la
mÃ¡quina y la entrada del usuario.

\item[/etc] contiene los archivos de configuraciÃ³n del sistema y de muchos de
los programas instalados en el sistema.  AdemÃ¡s, contiene los scripts de
inicio que se ejecutan cuando arranca la mÃ¡quina.  Generalmente los archivos
que se encuentran en este directorio pueden ser editados sÃ³lo por el
administrador de la mÃ¡quina, es decir el superusuario, normalmente llamado
``root''.

\item[/home] en este directorio se encuentran los directorios principales de los
usuarios.  En estos directorios los usuarios tienen permisos de leer, escribir y
ejecutar segÃºn deseen.  

\item[/lib] contiene las librerÃ­as necesarias para ejecutar los comandos que
se encuentran en /bin y /sbin.  Las librerÃ­as son rutinas que los programas
utilizan frecuentemente, y pueden ser compartidas por varios programas al mismo
tiempo.

Esto se debe a que las librerÃ­as no estÃ¡n incluidas dentro de los
programas, para que sea sencillo reusar el cÃ³digo, y aprovechar mejor el
espacio. 

En otros sistemas UNIX, las librerÃ­as pueden estar incluidas en los
comandos, con lo cual este directorio no es necesario.

\item[/sbin] contiene los archivos ejecutables que son necesarios para poder
administrar el sistema.  


\item[/usr] contiene archivos que serÃ¡n utilizados una vez que el sistema ya
estÃ¡ funcionando.  No son imprescindibles para el funcionamiento del sistema.

Por dentro se subdivide nuevamente en un Ã¡rbol muy parecido al del directorio
raÃ­z.

Encontramos, ademÃ¡s, directorios como {\bf src} (donde se suelen guardar los
archivos con el cÃ³digo fuente del sistema), {\bf games} (que tiene juegos), \
{\bf X11R6} (que contiene el sistema X), {\bf share} (que contiene archivos a
los que pueden acceder todos los programas y todos los usuarios). 

\end{description}

\subsection{Los archivos por dentro}

El contenido de un archivo comÃºn no es mas que una sucesiÃ³n de bytes, pero
cÃ³mo estÃ¡ esta informaciÃ³n almacenada y cÃ³mo accedemos a ella es mÃ¡s
interesante. Para tener una idea de cÃ³mo se guarda la informaciÃ³n en los
sistemas UNIX veremos el manejo de {\it inodos}.  

\subsubsection{Inodos}

Un inodo contiene el tamaÃ±o de un archivo, las tres fechas relacionadas con
el archivo (modificaciÃ³n del contenido, acceso al contenido y modificaciÃ³n
del inodo), los permisos, el dueÃ±o, el grupo, el nÃºmero de links, e
informaciÃ³n sobre dÃ³nde estÃ¡n fÃ­sicamente los datos (los bytes) del
archivo en el disco. 

Notemos que el nombre del archivo no estÃ¡ guardado en el inodo.

De esta forma, un directorio es simplemente un archivo que contiene
una lista de nÃºmeros de inodos y nombres de archivos. 

\subsubsection{Links}

Dentro del inodo se guarda el nÃºmero 
de links del archivo.  Un link es una entrada en un directorio, es decir en la
lista de inodos y nombres de archivos.  Un archivo puede tener muchos links.
Esto significa que dos archivos con distinto nombre pueden apuntar a un mismo
inodo, y por lo tanto tener el mismo contenido.  Son el mismo archivo con dos
nombres diferentes. 

Es importante recalcar que una vez creado el link, es imposible decir cuÃ¡l es
el nuevo archivo y cuÃ¡l es el que ya estaba creado. Si borramos uno de estos
archivos, no se borrarÃ¡ el contenido del archivo, sino Ãºnicamente la entrada
de directorio, y se decrementarÃ¡ la cantidad de links al inodo.  Solamente
se eliminarÃ¡ el contenido del archivo cuando el nÃºmero de links llegue a
cero. 

A este tipo de links se los llama {\it hard links}, existe otro tipo de links,
llamado {\it soft links} o tambiÃ©n {\it symlinks} (Symbolic Link).  
Estos links no comparten el  inodo del otro archivo, ni
aumentan la cantidad de links que tiene el otro archivo, porque se trata
Ãºnicamente de un puntero a otro archivo, que se puede encontrar en cualquier
parte del sistema de archivos.  Es muy similar al {\it Acceso Directo} 
de Windows.

Dado que los datos de los inodos se guardan por separado en cada dispositivo (es
decir, particiÃ³n de disco, CD, floppy, etc), no es posible crear {\it hard
links} entre dispositivos diferentes.  Sin embargo, sÃ­ es posible crear {\it
symlinks}.

\subsubsection{ln}

El comando \verb!ln! nos permite crear tanto {\it hard links} como 
{\it soft links}. 

Para crear un hard link deberemos escribir \verb!ln viejo nuevo!.  De tal
manera que \verb!nuevo! estarÃ¡ asignado al mismo inodo al que ya estaba asignado
\verb!viejo!.  Si hacemos \verb!ls -li! del directorio actual, podemos ver el
nÃºmero de inodo en la primera columna, y el nÃºmero de links en la tercera.
veremos que tanto \verb!viejo! como \verb!nuevo! 
tienen el mismo nÃºmero de inodo y de links.

Para crear un {\it symlink} utilizamos \verb!ln -s viejo nuevo!.  
En este caso, al hacer \verb!ls -li! vemos que \verb!nuevo! tiene un 
inodo diferente a \verb!viejo!, y que
en el nombre aparece la ruta a la que apunta.

\subsection{Permisos}

Como ya dijimos antes, todos los archivos tienen un dueÃ±o y un grupo.  Para
ver el dueÃ±o y el grupo, podemos hacer \verb!ls -l!, la tercera columna es el
usuario y la cuarta el grupo.

Analizaremos la primera columna (que puede parecer un jeroglÃ­fico, pero
lo que nos indica es los permisos que tiene cada archivo).

El primer caracter nos indica quÃ© tipo de archivo es.  Si tiene una 
\verb!"d"! es un directorio, si tiene una \verb!"l"! 
es un symlink, si tiene un \verb!"-"! es un archivo comÃºn.

Los siguientes tres caracteres indican los permisos que tiene el archivo para el
dueÃ±o.  La primera columna indica lectura, y puede tener una \verb!"r"! si
estÃ¡ habilitado el permiso o \verb!"-"! si no lo estÃ¡.
La segunda indica permiso de escritura, y puede tener una 
\verb!"w"! si estÃ¡ habilitado o un \verb!"-"! si no lo estÃ¡, la tercera indica
ejecuciÃ³n, y puede tener una \verb!"x"! si estÃ¡ habilitado o un \verb!"-"!
si no lo estÃ¡.

Los otros tres caracteres son los permisos para el grupo, y los Ãºltimos tres
son los permisos para el resto de los usuarios. \\

En el caso de los directorios, el permiso de lectura significa que se 
puede listar el
contenido del directorio, haciendo -por ejemplo- \verb!echo dir/*!, 
el permiso de escritura significa 
que se pueden crear y borrar archivos en el directorio
y el permiso de ejecuciÃ³n significa que se pueden buscar archivos, 
hacer un \verb!cd!, etc. 

\subsubsection{chmod}

Para cambiar los permisos de un archivo utilizamos el comando \verb!chmod!.
Solamente el dueÃ±o de un archivo (o el administrador del sistema) puede
cambiarle los permisos a un archivo.  AÃºn si no tiene ninguno de los
permisos explicados, el dueÃ±o del archivo siempre tiene permiso de cambiar
los permisos de un archivo.

Hay dos maneras diferentes de utilizarlo.  Podemos sumar 
o restar permisos a los
que ya estÃ¡n, o bien configurar todos los permisos a la vez.

Si queremos sumar o restar determinados permisos, utilizamos la 
siguiente sintaxis: \\
\verb!chmod quien+que archivo!. donde \verb!"quien"! puede ser:
\verb!u! (usuario dueÃ±o), \verb!g! (grupo), \verb!o! (otros), o bien
\verb!a! (todos). Y \verb!"que"! puede ser \verb!r!, \verb!w! o \verb!x!.
Los permisos que no se agreguen ni quiten permanecerÃ¡n como estaban.

AsÃ­, si escribimos \verb!chmod u+r archivo! le estamos agregando permiso 
de lectura al usuario.  Si hacemos \verb!chmod o-w archivo! le quitamos permiso
de lectura a los demÃ¡s.  Por otro lado, escribiendo la lÃ­nea
\verb!chmod a+x,go-w archivo! le
agregamos permiso de ejecuciÃ³n a todos los usuarios, y le quitamos el de
escritura a todos los que no son el dueÃ±o. \\

Por otro lado, existe una manera mÃ¡s rÃ¡pida, pero tambiÃ©n un poco mÃ¡s
complicada de cambiar los permisos.  Esta manera utiliza nÃºmeros octales.
Consideramos \verb!r = 4!, \verb!w = 2! y \verb!x = 1!.  
El valor del permiso que queremos 
asignar serÃ¡ la suma de los permisos.  Y lo tenemos que escribir para el
usuario, el grupo y los otros.

Ejemplo: \verb!chmod 644 archivo! asigna permisos de lectura y escritura para el
usuario y sÃ³lo de lectura para los demÃ¡s.  \verb!chmod 755 archivo! asigna
permisos de lectura, escritura y ejecuciÃ³n al usuario y de lectura y
ejecuciÃ³n a los demÃ¡s. \\

Si deseamos cambiar los permisos dentro de un directorio, de forma {\it
recursiva}, podemos utilizar la opciÃ³n \verb!-R!.

\subsubsection{groups - chgrp}

Un usuario puede pertenecer a varios grupos.  Para ver a quÃ© grupos
pertenece, utilizamos el comando \verb!groups!.

Y el comando \verb!chgrp grupo archivo! nos permite cambiar el grupo de un 
archivo.  Solamente podemos cambiar el grupo a otro grupo que tambiÃ©n 
pertenezcamos.

\subsubsection{chown}

Este comando solamente lo puede ejecutar el superusuario, y le permite cambiar
el dueÃ±o de un archivo, pero como no tenemos permiso de superusuario, no
podemos utilizarlo.

\subsection{Ejercicios}

\begin{enumerate}
\item Indicar los comandos a utilizar para otorgarle a un archivo
cualquiera permisos de: \\
lectura y escritura solamente para el dueÃ±o del archivo; \\
lectura y ejecuciÃ³n para todos los usuarios; \\
lectura para todos los usuarios, y escritura solamente para el dueÃ±o del
archivo.
\item Crear un directorio (por ejemplo {\bf pruebadir}), y algunos archivos
dentro (por ejemplo, {\bf arch1 arch2 arch3}).  Cambiarle los permisos de
lectura, ejecuciÃ³n y escritura al directorio y probar diversos comandos:
\verb!echo prueba/*!, \verb!cd prueba!, \verb!touch prueba/arch4!,
\verb!rm prueba/arch3!, \verb!ls prueba!, etc.  De este modo se puede
apreciar quÃ© significan realmente los permisos de lectura, escritura y
ejecuciÃ³n en un directorio.

\end{enumerate}

\newpage

\section{vi}

Vi es un editor de texto para consola.  Es el editor de texto tradicional de
UNIX, y en muchos sistemas es el Ãºnico disponible, de manera que es importante
saber usarlo, aunque mÃ¡s no sea bÃ¡sicamente.

Para comenzar a editar un archivo deberemos escribir: \verb!vi archivo!, o bien
ejecutar \verb!vi!, y luego abrir el archivo con el comando adecuado.

En vi existen dos modos de trabajo: un modo de ediciÃ³n y un modo de comandos.  
Al
iniciar el programa, estamos en el modo de comandos.  Para ingresar al modo de
ediciÃ³n debemos apretar \verb!i!, o bien, {\bf Insert}.  
Para volver al modo de
comandos, utilizamos la tecla {\bf ESC}.  

Cuando estemos en el modo de
ediciÃ³n, todo lo que ingresemos serÃ¡ texto del archivo.  Cuando estemos en
el modo comandos, no.  A veces lo que escribamos no mostrarÃ¡ ninguna salida
inmediata en la pantalla. 

\subsection{Comandos BÃ¡sicos}

\begin{tabular}{ll}
{\bf :e archivo} &amp; abre el archivo. \\
{\bf :q} &amp; sale del programa, solo si ya se grabaron los cambios. \\
{\bf :q!} &amp; sale del programa sin grabar los cambios. \\
{\bf :w} &amp; graba el archivo. \\
{\bf :w archivo} &amp; graba el archivo con ese nombre (eq. Guardar Como) \\
{\bf :wq} &amp; graba el archivo y luego sale del programa. \\
\end{tabular} \\

\subsection{Teclas de Movimientos}

\begin{tabular}{llc|cll}
{\bf 0} &amp; inicio de lÃ­nea. &amp; &amp; &amp; {\bf \$} &amp; fin de lÃ­nea. \\
{\bf b} &amp; anterior palabra. &amp; &amp; &amp; {\bf w} &amp; prÃ³xima palabra. \\
{\bf h} &amp; izquierda. &amp; &amp; &amp; {\bf l} &amp; derecha. \\
{\bf k} &amp; arriba. &amp; &amp; &amp; {\bf j} &amp; abajo. \\
{\bf G} &amp; fin de archivo. &amp; &amp; &amp; \\
\end{tabular} \\

A la mayorÃ­a de estos comandos se les puede agregar un nÃºmero al 
principio.  El efecto de este nÃºmero serÃ¡ el de multiplicar el efecto 
del comando por el nÃºmero ingresado. Por ejemplo, {\bf 10j} se mueve 
10 lineas hacia abajo.

En el caso de {\bf G}, el nÃºmero que se le agregue antes puede ser
el nÃºmero de linea al cual deseamos ir.  Si deseamos ir a la primera
lÃ­nea del archivo, debemos escribir {\bf 1G}.

\subsection{Manejo de Texto}

Como en cualquier editor de texto, podemos cortar, copiar y pegar. \\

\begin{tabular}{ll}
{\bf dd} &amp; corta la lÃ­nea. \\
{\bf dw} &amp; corta la prÃ³xima palabra. \\
{\bf d\$} &amp; corta hasta el final de la lÃ­nea. \\
{\bf p} &amp; pega lo que se haya cortado o copiado \\
{\bf u} &amp; (undo) deshace la Ãºltima acciÃ³n. \\
{\bf yy} &amp; copia la lÃ­nea. \\
{\bf x} &amp; corta el caracter. \\
\end{tabular} \\

Muchos de estos comandos tambiÃ©n aceptan un nÃºmero que los 
preceda, de tal manera que se pueden seleccionar varios caracteres, palabras o 
lÃ­neas a un mismo tiempo.

\subsection{BÃºsquedas}

Ingresando {\bf /texto}, (ENTER) nos llevarÃ¡ a la 
prÃ³xima apariciÃ³n de 'texto'.
Para ir a la anterior: {\bf ?texto} (ENTER).
Una vez que lo hemos buscado, presionando {\bf n} iremos a la siguiente
apariciÃ³n, y presionando {\bf N} iremos a la anterior.

\subsection{Otros}

\begin{tabular}{ll}
{\bf CTRL-g} &amp; muestra la lÃ­nea actual y el total de lÃ­neas. \\
{\bf o} &amp; agrega una lÃ­nea debajo de la actual, y entra en modo inserciÃ³n.
\\
{\bf a} &amp; se coloca en el caracter siguiente al actual, y en modo inserciÃ³n.
\\
\end{tabular} \\ 

\subsection{MÃ¡s informaciÃ³n}

Dentro del mismo vi es posible obtener ayuda sobre cÃ³mo manejarlo,
utilizando el comando \verb!:help!, desde el modo comandos.  Para salir de
la ayuda y volver al archivo que se estaba editando: \verb!:q!.

Una de las versiones de vi mÃ¡s difundida es el vim (Vi Improved). Tiene 
muchas mÃ¡s caracterÃ­sticas, como resaltado de sintaxis (syntax highlighting) y
muchas otras cosas mÃ¡s. Para los reciÃ©n iniciados existe un comando
\verb!vimtutor!, que nos da unas breves clases sobre el uso de vim. 

\section{Emacs}

A pesar que emacs no se encuentra en todos los sistemas UNIX, y por lo tanto no
es una herramienta con la que podemos contar en cualquier caso, es uno de los
procesadores de texto mÃ¡s utilizados. En realidad es mucho mÃ¡s que un procesador
de texto, puede utilizarse como un lector de correo y de noticias, 
un navegador web, una interfaz para varios juegos, y hasta 
un entorno de programaciÃ³n y desarrollo. 

Esto es posible porque emacs es principalmente un intÃ©rprete del lenguaje 
LISP, un lenguaje que fue desarrollado para la investigaciÃ³n de inteligencia 
artificial. Dentro de emacs, es el intÃ©rprete de LISP 
quien ejecuta un editor de texto y el que interpreta cada uno de nuestras
entradas. Sin embargo, en esta introducciÃ³n utilizaremos simplemente sus
capacidades como editor de texto.

\subsection{Una breve recorrida}

Para ejecutar emacs podemos, desde la lÃ­nea de comandos escribir
\verb!emacs!, y dentro del emacs abrir el archivo que queramos editar. O
bien, abrir el archivo al entrar al emacs ejecutando \verb!emacs archivo!,
es posible, ademÃ¡s, comenzar a editar varios archivos a la vez, utilizando
\verb!emacs arch1 arch2 arch3!.

Para abrir un archivo dentro de emacs, se utilizan las
teclas {\bf Ctrl-x Ctrl-f}. Esto muestra un mensaje en la parte inferior de
la pantalla \verb!Find file: ~/!, que indica que a continuaciÃ³n
puede ingresarse el nombre del archivo a editar. 
Al igual que dentro del intÃ©rprete de comandos \verb!bash!, 
la tecla \verb!TAB! nos serÃ¡ de gran utilidad,
ya que completarÃ¡ automÃ¡ticamente el nombre del archivo, o desplegarÃ¡ 
una lista de los archivos que coincidan con el nombre que se escriba.

Una vez que hemos escrito lo
suficiente, se puede grabar utilizando {\bf Ctrl-x Ctrl-s}.

Para salir de emacs usamos las teclas {\bf Ctrl-x Ctrl-c}.
emacs preguntarÃ¡ si
queremos guardar los cambios hechos, contestando \verb!"y"! se grabarÃ¡n los
cambios, mientras que \verb!"n"! no los grabarÃ¡, y \verb?"!"? no guardarÃ¡
ningÃºn cambio.

\subsection{Meta y Control}

Emacs es un editor que no tiene mÃºltiples modos como el vi. Es decir,
en cuanto se abre el editor ya estÃ¡ listo para que empieces a
escribir y todo lo que se escriba lo incluirÃ¡ en el archivo que se estÃ¡
editando.

Para acceder a un comando del editor debemos apretar una combinaciÃ³n
de teclas. Para eso usamos unas teclas denominadas Meta y Control
junto con otras teclas. Estas teclas no se muestran en el texto, son
Ã³rdenes al editor. La tecla Meta en la mayorÃ­a de las PCs modernas no
existe y en su reemplazo puede encontrarse la tecla ALT o la tecla
'windows'.

TambiÃ©n es posible usar la tecla ESC como reemplazo de la tecla
Meta. Pero en ese caso la tecla ESC no es apretada al mismo tiempo que
la otra tecla, sino que apretamos primero la tecla ESC, la soltamos y luego
apretamos la tecla que dispare el comando o acciÃ³n del editor.

Por ejemplo, para acceder al tutorial debemos apretar 
{\bf Ctrl-h t}, 
esto significa apretar la tecla Control al mismo tiempo que la
tecla h y luego la tecla t. Por comodidad, dentro de los tutoriales y
ayudas de emacs (y tambiÃ©n dentro de esta breve introducciÃ³n), se 
escriben estas combinaciones con una C para Control y una M para Meta.

\subsection{Ventanas (Buffers)}
\label{sec:buffers}

emacs es un editor que nos permite trabajar con mÃºltiples archivos
a la vez. Cada archivo lo deja disponible a travÃ©s de distintos
{\it buffers}, que son distintas ventanas a las que el usuario puede 
acceder; puede cambiar de una ventana a otra en cualquier
momento o tener varias ventanas de texto a la vista dentro de la misma pantalla
(dividiÃ©ndola al medio, en cuartos, en octavos, etc). 

Para obtener una lista de las distintas ventanas disponibles, podemos apretar
{\bf C-x b}, esto dividirÃ¡ la pantalla actual en dos y en la
parte inferior tendremos una lista de todas las ventanas 
disponibles. Con {\bf C-x o} podemos pasar de la ventana superior a
la inferior, y viceversa.

A continuaciÃ³n, algunas otras teclas que pueden llegar a resultar 
Ãºtiles en el manejo de ventanas. \\

\begin{tabular}{ll}
{\bf C-x 2} &amp; Divide la ventana actual en dos partes horizontales \\
{\bf C-x 3} &amp; Divide la ventana actual en dos partes verticales \\
{\bf M-C-v} &amp; Avanza una pantalla en la otra ventana \\
{\bf C-x o} &amp; Cambia de ventana \\
{\bf C-x b} &amp; Muestra una lista de todas las ventanas disponibles \\
{\bf C-x k} &amp; Cierra la ventana actual \\
{\bf C-x 0} &amp; Cierra la otra ventana 
\end{tabular}

\subsection{Algunas combinaciones de teclas}

A continuaciÃ³n, algunas otras combinaciones de teclas
que pueden resultar Ãºtiles en el uso de emacs.

\subsubsection{Deshacer y volver a hacer}

Para deshacer el Ãºltimo cambio realizado, se utiliza la combinaciÃ³n
{\bf C-\_}.  Esta combinaciÃ³n puede presionarse tantas veces como se desee
para ir deshaciendo todos los cambios realizados.

Si, llegado un punto, si quiere volver a realizar los cambios que se han
deshecho, simplemente se realiza cualquier cambio (por ejemplo, escribir un
caracter) y luego se vuelve a presionar {\bf C-\_} tantas veces como sea
necesario.

\subsubsection{Teclas de movimientos}

Dentro de emacs es posible utilizar los cursores para moverse a travÃ©s del
texto del archivo, pero ademÃ¡s es posible utilizar estas teclas. \\

\begin{tabular}{llc|cll}
{\bf C-n} &amp; Baja una lÃ­nea &amp; &amp; &amp; {\bf C-p} &amp; Sube una lÃ­nea \\
{\bf C-f} &amp; Avanza un caracter &amp; &amp; &amp; {\bf C-b} &amp; Retrocede un caracter \\
{\bf M-f} &amp; Avanza una palabra &amp; &amp; &amp; {\bf M-b} &amp; Retrocede una palabra \\
{\bf C-a} &amp; Principio de lÃ­nea &amp; &amp; &amp; {\bf C-e} &amp; Fin de lÃ­nea \\
{\bf M-a} &amp; Principio de oraciÃ³n &amp; &amp; &amp; {\bf M-e} &amp; Fin de oraciÃ³n \\
{\bf M-arriba} &amp; Principio de pÃ¡rrafo &amp; &amp; &amp; {\bf M-abajo} &amp; Fin de pÃ¡rrafo \\
{\bf C-v} &amp; Sube una pantalla &amp; &amp; &amp; {\bf M-v} &amp; Baja una pantalla \\
{\bf M-$&lt;$} &amp; Principio de la ventana &amp; &amp; &amp; {\bf M-$&gt;$} &amp; Fin de la ventana
\end{tabular}

\subsubsection{Teclas para copiar y pegar}

En emacs, para poder copiar y pegar, primero se inicia la selecciÃ³n del
texto, luego se mueve el cursor hasta el final de la selecciÃ³n (el programa
normalmente no indica que se estÃ¡ marcando el texto), y una vez que se
llega al final de la selecciÃ³n se presiona la combinaciÃ³n correspondiente a
cortar o copiar, segÃºn se desee.

\begin{tabular}{ll}
{\bf C-espacio} &amp; Comenzar a marcar \\
{\bf C-w} &amp; Cortar la regiÃ³n marcada \\
{\bf M-w} &amp; Copiar la regiÃ³n marcada \\
{\bf C-y} &amp; Pegar la regiÃ³n que se haya cortado o copiado.
\end{tabular}

\subsubsection{Teclas para realizar bÃºsquedas}

\begin{tabular}{ll}
{\bf C-s} &amp; Busca hacia abajo \\
{\bf C-r} &amp; Busca hacia arriba \\
{\bf C-s C-s} &amp; Repite la bÃºsqueda \\
{\bf M-C-s} &amp; Busca utilizando una {\it expresiÃ³n regular} \\
{\bf M-\%} &amp; Reemplaza en el texto, con confirmaciÃ³n
\end{tabular}

\subsubsection{Teclas de borrado}

\begin{tabular}{ll}
{\bf C-d} &amp;  Borra un caracter \\
{\bf M-d} &amp;  Borra una palabra \\
{\bf M-del} &amp; Borra la palabra anterior \\
{\bf C-k}  &amp; Borra una lÃ­nea \\
{\bf M-k} &amp; Borra una oraciÃ³n 
\end{tabular}

\newpage

\section{Scripts de Shell - BÃ¡sicos}

Siempre que interactuamos con el shell estamos creando pequeÃ±os programas.
Cuando a estos pequeÃ±os programas los guardamos en un archivo que pueda
ejecutarse luego, lo llamamos un ``script''.  Estos scripts sirven, entre otras
cosas,  para tareas de automatizaciÃ³n.

Los scripts de shell son bÃ¡sicamente programas escritos en el lenguaje del
shell, se parecen a los archivos .BAT del DOS.  Aunque es cierto que, si se van
a escribir mÃ¡s de varias decenas de lÃ­neas de script, es mejor recurrir a un
lenguaje diferente del shell, pensar en que los scripts de shell son solamente
pequeÃ±os programas serÃ­a cometer una injusticia con la flexibilidad y
comodidad que ofrecen al usuario.

Normalmente los scripts de shell se crean cuando es necesario combinar en una
Ãºnica acciÃ³n una tarea rutinaria.

Estos scripts pueden ser muy breves (una sola lÃ­nea),
o bastante largos (varias pantallas).
Vamos a empezar con algunos ejemplos muy sencillos. 

\subsection{Primer Script de Shell}

Creamos un archivo que contenga: \verb!who | wc -l!, esto lo podemos hacer
utilizando el comando \verb!echo!, con la salida estÃ¡ndar a un archivo, o bien
utilizando el editor vi.  El archivo lo llamaremos \verb!cuantos!.

Para poder ejecutar este pequeÃ±o script, tenemos que utilizar el
intÃ©rprete del shell.  Hay dos formas de hacerlo: \verb!sh cuantos!,
invocarÃ¡ al sh para que interprete nuestro script y lo ejecute.

El archivo no lo podemos ejecutar directamente, porque al crearlo, lo hemos
creado como archivo de texto, y no tiene permisos de ejecuciÃ³n.  Para que
podamos ejecutarlo tenemos que agregarle el permiso: \verb!chmod u+x cuantos!.
Una vez que le hemos agregado el permiso, nuestro archivo ha pasado a ser un
ejecutable, y se lo puede invocar como a cualquier comando.  La lÃ­nea para
invocarlo serÃ¡: \verb!./cuantos!.

\subsection{La variable PATH}

Llama la atenciÃ³n el {\bf ./} que tenemos que agregar al principio 
para poder ejecutar el archivo.  Esto simboliza al directorio actual.  
Lo que estamos haciendo es diciÃ©ndole al shell que busque el archivo 
``cuantos'' en el directorio actual.  
Esto se debe a que el directorio actual no estÃ¡ en la
lista de los directorios en los que el shell busca para encontrar un determinado
comando.

Los directorios en los que el shell busca son {\bf /bin}, {\bf /usr/bin} y
algunos otros.  EstÃ¡n definidos en una variable llamada PATH.

Para poder ver el contenido de la variable PATH, podemos ejecutar
desde lÃ­nea de comandos: \verb!echo $PATH!.
Es importante recalcar que la variable se llama {\bf PATH}, pero para
ver su contenido le agregamos el sÃ­mbolo \$ adelante, este sÃ­mbolo es un
meta-caracter de shell, como los vistos anteriormente, y le dice al shell que lo
que viene a continuaciÃ³n es una variable.

\subsection{Variables de entorno}

AsÃ­ como PATH tambiÃ©n existen muchas otras variables.  Algunas determinadas
por el sistema, y otras determinadas por nosotros.  

Llamamos {\it entorno} al conjunto de variables, como 
el PATH, el nombre de usuario,
el directorio actual, el directorio principal, las preferencias de lenguaje,
etc. que determinan a la consola que estamos utilizando en este momento.
Podemos ver cuales son las variables de nuestro entorno escribiendo:
\verb!set!.

A estas variables de entorno, nosotros podemos agregar nuevas variables.   Para
ello podemos escribir: \verb!variable=valor!.  Y haciendo 
\verb!echo $variable! podremos ver el valor que le asignamos a la variable.

Al ejecutar un programa, este programa recibe una copia de nuestro entorno,
donde algunas variables pueden mantenerse (variables exportadas), y otras 
pueden no estar.  Un programa puede modificar las variables que tiene en su
entorno, pero no las del entorno anterior.
A su vez, dentro de ese programa podemos ejecutar un nuevo programa, que
tendrÃ¡ su propio entorno, con sus propias variables.

Para hacer que los programas hereden las variables que nosotros definamos,
existe un comando llamado \verb!export!, que nos asegura que los programas que
se ejecuten, reciban esa variable en su entorno. \\

{\bf Ejemplos}
\begin{itemize}

\item Escriba en la consola \verb!dia=sabado!, cree un script que contenga:
  \verb!echo Hoy es $dia!. Ejecute el script, a coninuaciÃ³n ejecute
  \verb!export dia! y vuelva a ejecutar el script. Explique lo sucedido.

\item Crear otro script, que contenga: \verb!variable2=valor2;export variable2; echo $variable2!.
  Ejecutar el script, y luego, desde la lÃ­nea de comandos \verb!echo $variable2!.
  Esto no nos mostrarÃ¡ nada, ya que como dijimos antes, no se puede modificar
  el entorno anterior.

\item Crear otro script, que contenga: 
  \verb!cd /; pwd; echo $PWD; export PWD!.  Al ejecutar el script, notar que
  por mÃ¡s que tanto el \verb!pwd! como el \verb!echo! nos haya mostrado que el
  \verb!cd! habÃ­a logrado cambiar de directorio, al volver del script,
  permanecemos en el directorio en el que estÃ¡bamos al ejecutar el script.

\end{itemize}

\subsection{ParÃ¡metros de los comandos}

Cuando ejecutamos un comando, puede suceder que necesite parÃ¡metros.  En el
caso de los scripts, los parÃ¡metros se encuentran en variables especiales que
identificamos como \$1, \$2, \$3, etc.  El nombre de la variable nos indica la
ubicaciÃ³n del parÃ¡metro.

Para ver esto en un script muy sencillo, armaremos un script que contenga la
lÃ­nea \verb!echo $1!, de forma que -al invocarlo- nos mostrarÃ¡ el
parÃ¡metro que le pasemos al ejecutarlo. \\

Para tener el caso de un script un poco mÃ¡s Ãºtil,
vamos a hacer un script que nos permitirÃ¡ convertir rÃ¡pidamente
en ejecutables a los prÃ³ximos scripts que realicemos: \verb!chmod +x $1!. Le
pondremos de nombre {\bf cx}.
Para hacer ejecutable este script, vamos a aprovechar lo que ya escribimos y
haremos: \verb!sh cx cx!.

Podemos mejorar este script, de tal manera que reciba mÃ¡s parÃ¡metros y
pueda hacer ejecutables mÃ¡s archivos a la vez.  PodrÃ­amos escribir, por
ejemplo. \verb!chmod +x $1 $2 $3 ...!, pero existe una manera mÃ¡s
elegante (y mÃ¡s eficiente): \verb!chmod +x $*!. Al encontrar el \$*, el
shell lo reemplazarÃ¡ por todos los parÃ¡metros que haya recibido el script.
\\

Por Ãºltimo, veremos la utilidad de las comillas dobles (\verb!"!), en su
relaciÃ³n con los parÃ¡metros.  Usaremos un script que contenga la lÃ­nea:
\verb!echo "Buen dÃ­a $1"!.  Al ejecutarlo con un parÃ¡metro (por ejemplo,
Pedro), la salida del comando serÃ¡ \verb!Buen dÃ­a Pedro!.

Si en el ejemplo anterior hubiÃ©ramos utilizado comillas simples, la salida
del comando hubiera sido \verb!Buen dÃ­a $1!, ya que dentro de las comillas
simples el meta-caracter \verb!$! no es interpretado, mientras que dentro de
las comillas dobles si.

\section{Filtros - BÃ¡sicos}

Existen una gran variedad de programas que reciben una entrada, la procesan y
emiten una salida, a este tipo de programas le llamamos filtros. Estos son una
parte fundamental del sistema ya que relacionando filtros simples se puede
conseguir prÃ¡cticamente cualquier cosa, a nivel de administraciÃ³n de
archivos y scripts..

Entre estos filtros estÃ¡n: \\

\begin{tabular}{ll}
cat &amp; para mostrar la entrada. \\
grep, tail, head y cut &amp; para seleccionar una parte de la entrada. \\
less y more &amp; para paginar la entrada. \\
sort &amp;  para ordenar la entrada\\
tr &amp; para alterar la entrada en forma ordenada. \\
comm y diff &amp; para comparar dos entradas. \\
wc &amp; para contar la entrada.
\end{tabular}

\subsection{grep}

Un comando muy Ãºtil que nos proporciona UNIX es \verb!grep!.  Su funciÃ³n
principal es imprimir por pantalla solamente las lÃ­neas que concuerden con un
patrÃ³n que nosotros le indicamos.

Por ejemplo: \verb!ls -l | grep archivo!, nos mostrarÃ¡ todas 
las lÃ­neas  del \verb!ls -l! que concuerden con \verb!archivo!. 

Algunas opciones de grep son: 
\begin{itemize}
\item \verb! -i! (ignore case) que no tiene en cuenta mayÃºsculas y minÃºsculas. 
\item \verb! -n! para que muestre el nÃºmero de lÃ­nea dentro del archivo.
\item \verb! -v! para que muestre las lÃ­neas que no concuerdan con la
palabra ingresada.
\end{itemize}

Vamos a hacer un ejemplo de una agenda sencilla, utilizando el comando grep y
unos scripts de shell.  En primer lugar necesitamos tener un archivo con unas
cuantas lÃ­neas de la forma: ``nombre: telÃ©fono''.  Por lo menos cuatro o cinco
lÃ­neas, como para probar este ejemplo.

Una vez que hemos creado el archivo, crearemos el script, que se llamarÃ¡ 110,
y deberÃ¡ contener la siguiente lÃ­nea: \verb!grep -i "$*" agenda!.  Y para
buscar un telÃ©fono dentro de nuestra agenda haremos: \verb!110 nombre!.

\subsection{tail}

El comando \verb!tail! nos permite ver la cola de un archivo, es decir sus 
Ãºltimas lÃ­neas (Ãºltimas 10 por omisiÃ³n). Esto, aunque a simple vista no
parezca Ãºtil, resulta de gran utilidad para ver archivos grandes como, por
ejemplo, logs (archivos donde se guardan mensajes de estado y/o de errores).

Para probar el comando vamos a utilizar los logs del sistema, que se suelen
guardar en /var/log, en particular
/var/log/messages es el archivo que contiene gran parte de los mensajes del
sistema. Podemos hacer \verb!tail /var/log/messages! y compararlo con la salida
de \verb!cat /var/log/messages!.

AdemÃ¡s a \verb!tail! podemos indicarle cuÃ¡ntas lÃ­neas queremos que nos 
muestre. Con la opciÃ³n -20, por ejemplo, le dirÃ­amos que nos 
muestre 20 lÃ­neas y asÃ­ con cualquier nÃºmero que le pasemos. 
TambiÃ©n podemos decirle que nos muestre el contenido del archivo a partir de 
una determinada lÃ­nea, por ejemplo \verb!tail +5 archivo! nos mostrarÃ¡ 
el contenido del archivo desde la lÃ­nea 5 en adelante. \\

Otro comando similar a \verb!tail! es \verb!head!.  Su comportamiento es muy
similar, pero en lugar de mostrar las Ãºltimas lÃ­neas de la entrada, muestra
las primeras.

\subsection{sort}

Este comando nos permite obtener una salida ordenada, si hacemos 
\verb! ls | sort! obtendremos la salida de ls con un orden alfabÃ©tico.

Ahora probemos \verb!ls -i | sort!, \verb!sort! ordena la salida de \verb!ls!
alfabÃ©ticamente, eso quiere decir que los nÃºmeros no van a estar ordenados
de menor a mayor sino en orden alfabÃ©tico. Para ordenarlos numÃ©ricamente
existe la opciÃ³n -n, \verb!ls -i | sort -n!  producirÃ¡ una salida ordenada
de menor a mayor.  Si quisiÃ©ramos, en cambio, que lo ordene de mayor a
menor, debemos usar \verb!ls -i | sort -nr!, es decir -r ordena en orden
inverso. \\

TambiÃ©n podemos ordenar por una determinada columna, para entender esto de
una manera mÃ¡s clara veamos la salida de \verb!ls -l!, estas lÃ­neas pueden
ser ordenadas por tamaÃ±o, por nombre, por fecha, etc.  Para eso tenemos que
indicarle cuÃ¡l columna tiene que ordenar y con quÃ© criterio. 
Notar que sort cuenta las columnas empezando de 0.

Por ejemplo:

\verb!ls -l | sort +4nr! ordena la salida de \verb!ls! por el 
tamaÃ±o dejando los mÃ¡s chicos al final. En este caso, la n, que indica
ordenamiento numÃ©rico es opcional, ya que \verb!sort! decide
automÃ¡ticamente el ordenamiento.

\verb!ls -l | sort +4n +8! ordena la salida de \verb!ls! primero 
por tamaÃ±o y luego por el nombre del archivo. En este caso, es necesario
poner la n, que indica ordenamiento numÃ©rico. \\

TambiÃ©n existe un opciÃ³n -u que nos permite eliminar las lineas iguales
adyacentes de la salida de sort.  Es decir que si nuestra salida produce dos
lÃ­neas iguales una debajo de otra, verÃ­amos solamente una lÃ­nea.

\subsection{tr}

Este comando nos permite transliterar caracteres, es decir cambiar determinado
caracter por otro. Si escribimos \verb!tr 'a-z' 'A-Z' &lt; archivo!, 
veremos que tr transforma todas las minÃºsculas en mayÃºsculas.  

Los parÃ¡metros del ejemplo anterior son rangos (de la 'a' a la 'z' y de la
'A' a la 'Z'), pero no es necesario que lo sean. 
Lo que sÃ­ nos exige \verb!tr! es que los parÃ¡metros tengan
la misma cantidad de caracteres, o bien que el segundo sea un solo caracter. 
En este Ãºltimo caso reemplazarÃ¡
todos los caracteres del primer parÃ¡metro con el del segundo.

La opciÃ³n \verb!-c! indica que deben transliterarse todos los caracteres 
que no estÃ©n incluidos en el primer parÃ¡metro. \\

Ejemplo difÃ­cil:

\verb!cat archivo | tr -c 'a-zA-Z' '\n' | tr 'A-Z' 'a-z' | sort -u! 

El primer \verb!tr! convierte todo lo que no sea letras en \verb!\n! (retorno
de carro), el segundo convierte todas las mayÃºsculas en minÃºsculas y el
\verb!sort! del final las ordena alfabÃ©ticamente eliminando las lÃ­neas
iguales, con lo que obtenemos una palabra por lÃ­nea.

\subsection{comm}

Este comando nos sirve para comparar el contenido de dos archivos, lÃ­nea por
lÃ­nea.  Para poder probar este comando, debemos crear dos archivos parecidos,
que tengan unas cuantas lÃ­neas en comÃºn, y otras distintas.  Luego, debemos
hacer: \verb!comm archivo1 archivo2!

La salida estÃ¡ separada en tres columnas: en la primera columna 
estarÃ¡n las lÃ­neas que estÃ¡n en el primer archivo y no en el segundo, 
en la segunda columna veremos las lÃ­neas del segundo archivo 
que no estÃ©n en el primero y
por Ãºltimo, en la tercera columna, las que estÃ¡n en los dos.

AdemÃ¡s podemos indicar cuÃ¡l de esas columnas no queremos que muestre, por
ejemplo, utilizando: \verb!comm -12 arch1 arch2! muestra solamente la tercera columna, 
es decir, las lÃ­neas que estÃ¡n en ambos archivos. 

El problema que tiene \verb!comm! es que espera que las lÃ­neas estÃ©n
ordenadas alfabÃ©ticamente, o en la misma posiciÃ³n dentro del archivo.  De
modo que puede suceder que archivos muy similares sean procesados por
\verb!comm! como archivos muy diferentes.  Para procesamiento mÃ¡s avanzado
de diferencias de archivos puede utilizarse el comando \verb!diff!. \\

Ejemplo:

En {\bf /usr/share/dict/} normalmente tenemos un archivo diccionario, en el
cual encontramos una palabra por renglÃ³n. En especial, el archivo {\bf
words} suele ser un symlink al diccionario del idioma de nuestro sistema. 

Lo que vamos a hacer es armar un pequeÃ±o analizador ortogrÃ¡fico, 
usando los filtros reciÃ©n vistos.
Utilizaremos \verb!comm! para verificar si la palabra estÃ¡ en el
diccionario, y que nos avise si no estÃ¡. 
Primero deberemos llevar el texto a una palabra por lÃ­nea ordenada 
alfabÃ©ticamente (que es el ejemplo que utilizamos con \verb!tr!). 
Y luego, utilizar \verb!comm! para comparar con el diccionario. \\

El comando completo serÃ¡: 
\begin{verbatim}
cat archivo | tr -c 'a-zA-Z' '\n' | tr 'A-Z' 'a-z' | sort -u |
comm -23 - /usr/share/dict/words
\end{verbatim}

Notar que el - como parÃ¡metro del \verb!comm! le indica que use la entrada
estÃ¡ndar para leer el primer archivo.

\section{Filtros - Avanzados}

Existen, ademÃ¡s de los filtros que ya vimos, otros dos filtros muy
poderosos, llamados \verb!sed! y \verb!awk!. Tienen una sintaxis tan avanzada
que se los considera pequeÃ±os lenguajes de programaciÃ³n. En este curso no
los vamos a estudiar. 

Sin embargo, gran parte de la potencia de estos es su manejo de expresiones 
regulares que es el mismo que el de \verb!grep!, que veremos a continuaciÃ³n.

\subsection{grep}

Como ya vimos, podemos hacer \verb!grep patrÃ³n archivos! y veremos las
lÃ­neas que concuerdan con el patrÃ³n en esos archivos,

La gran fortaleza de \verb!grep! se encuentra en la sintaxis
del patrÃ³n. Hasta ahora, el patrÃ³n que ingresÃ¡bamos era simplemente una
palabra, y eso le indicaba a \verb!grep! que debÃ­a encontrar las lÃ­neas que
contuvieran esa palabra.

Sin embargo, en ese patrÃ³n podemos incluir lo que se llama una {\it expresiÃ³n
regular}.  Las expresiones regulares son cadenas de caracteres que permiten
transmitirle a los filtros una bÃºsqueda mucho mÃ¡s avanzada.  Tenemos la
posibilidad, por ejemplo, de indicar si queremos que algo estÃ© al principio o
al final de un archivo, si queremos que estÃ© repetido una determinada cantidad
de veces, etc. 

\begin{itemize}

\item El sÃ­mbolo \verb!^!  indica comienzo de lÃ­nea, es decir que el patrÃ³n que
estÃ© a continuaciÃ³n debe estar al principio de la lÃ­nea.

Por ejemplo, podemos querer ver todas las lÃ­neas del comando \verb!who! que
comienzan con un nombre de usuario en particular.  Esto lo harÃ­amos
ejecutando: \verb!who | grep ^usuario!. 

\item De una manera similar \$ al final de un patrÃ³n significa que debe estar
  ubicado al final de la lÃ­nea.

\item El . actÃºa como el ? en el shell, concuerda con cualquier caracter, una
  sola vez.

Por ejemplo, si hacemos \verb!ls -l | grep '^.......rw'! veremos los archivos
que tengan permisos de lectura y escritura para el resto mundo. 

\item TambiÃ©n tenemos un manejo de rangos \verb![...]! muy parecido al del
  shell.

\item El * nos permite que el Ãºltimo caracter se encuentre 0 o mÃ¡s veces. Es
  decir, utilizando \verb!.*! obtendremos el mismo comportamiento que el del
  \verb!*! de shell.

  Por ejemplo, \verb!ls -l | grep '^.*rw'! puede mostrarnos los archivos que
  tengan algÃºn permiso de escritura y lectura, o bien algÃºn archivo que
  contenga las letras rw en su nombre.
\end{itemize}

Un problema comÃºn es que muchos de los caracteres que \verb!grep! usa como
caracteres especiales son los mismos que usa el shell como meta-caracteres y
esto puede llegar a confundirnos mucho, por lo que usamos los patrones entre
comillas simples ('...') para evitar problemas de interpretaciÃ³n del shell.
Pero tambiÃ©n podemos querer que el grep no interprete determinado caracter en
ese caso usamos \verb!\ !.

\subsection{egrep o grep -E y fgrep o grep -F}

En realidad, grep es el primero de una familia de comandos, egrep tiene un set
de expresiones regulares mÃ¡s completo, mientras fgrep esta optimizado para
manejo de archivos grandes, pero solo busca literales. 

En la actualidad la versiÃ³n GNU de estos comandos resume los tres dentro de grep
con las opciones -E y -F, pero existen mÃ¡s, como el ngrep (network grep),
grepmail, etc.

\subsection{Expresiones de grep, egrep}

Se listan a continuaciÃ³n las expresiones de grep y egrep, 
por orden de precedencia, con una explicaciÃ³n somera de su significado. \\

\begin{tabular}{c|p{12cm}}
ExpresiÃ³n &amp; Significado \\
\hline
{\bf c} &amp; cualquier caracter no especial, concuerda a si mismo \\
{\bf $\backslash$c} &amp; cancela significado especial de c \\
{\bf \verb!^!} &amp; inicio de lÃ­nea \\
{\bf \$} &amp; fin de lÃ­nea \\
{\bf .} &amp; cualquier caracter individual \\
{\bf \verb![...]!} &amp; cualquiera de los caracteres en ...; 
incluye rangos de tipo a-z \\
{\bf \verb![^...]!} &amp; cualquiera de los caracteres que no estÃ© en ...; 
tambiÃ©n se incluyen los rangos a-z \\
{\bf r*} &amp; cero o mÃ¡s ocurrencias de r\\
{\bf r+} &amp; una o mÃ¡s ocurrencias de r (egrep)\\
{\bf r?} &amp; cero o una ocurrencia de r (egrep)\\
{\bf \verb!r1|r2!} &amp; expresiÃ³n r1 o expresiÃ³n r2 (egrep)\\
{\bf $\backslash$(r$\backslash$)} &amp; agrupar expresiÃ³n regular r (grep)\\
{\bf (r)} &amp; agrupar expresiÃ³n regular r (egrep)\\
{\bf $\backslash$num} &amp; lo que concordÃ³ con la num-Ã©sima expresiÃ³n regular agrupada\\
\end{tabular}

Ante la pregunta posible, que puede surgir mirando esta tabla, de cuÃ¡l es
el significado de \verb!(r)! cuando se utiliza grep, la respuesta es que
simplemente concuerda con los parÃ©ntesis, como cualquier caracter sin
significado especial

\subsection{Ejercicios}

Utilizando el diccionario que se encuentra en el directorio
{\bf /usr/share/dict}, encontrar las expresiones regulares que concuerdan
con los siguientes tipos de palabras.

\begin{enumerate}
\item PalÃ­ndromos de 3 letras (ej: ala, asa, ata).
\item PalÃ­ndromos de 4 letras (ej: erre).
\item PalÃ­ndromos desde 3 a 9 letras (ej: salas, rallar, anilina)
\item Palabras que tienen todas sus letras ordenadas alfabÃ©ticamente.
\item Palabras que tienen todas sus vocales ordenadas alfabÃ©ticamente.
\item Palabras que tienen todas las vocales. (ayuda: utilizar varios
\verb!grep! encadenados).
% Respuesta:
%grep '^[^aÃ¡]*[aÃ¡][^a]*$' /usr/share/dict/spanish | grep '^[^eÃ©]*[eÃ©][^eÃ©]*$' | grep '^[^iÃ­]*[iÃ­][^iÃ­]*$' | grep '^[^oÃ³]*[oÃ³][^oÃ³]*$' | grep '^[^uÃº]*[uÃº][^uÃº]*$'
\end{enumerate}

\section{MÃ¡s scripts de Shell}

AdemÃ¡s de las herramientas para manejo de variables que se explicaron
anteriormente, el shell nos permite utilizar herramientas para manejo de ciclos
y para estructuras condicionales, veremos a continuaciÃ³n cÃ³mo utilizar y
manipular los parÃ¡metros y luego ejemplos que utilizan {\bf if}, 
{\bf for}, {\bf while} y {\bf case}, junto con varias herramientas y
caracterÃ­sticas del shell, como manejo de funciones, valores de retorno, etc.

\subsection{ParÃ¡metros}

Como ya hemos visto, los scripts de shell pueden recibir y manipular
parÃ¡metros.  Estos parÃ¡metros se representan dentro de los scripts como \$1, 
\$2, etc.  El conjunto de todos los parÃ¡metros estÃ¡ representado por \$*,
mientras que la cantidad de parÃ¡metros estÃ¡ representada por \$\#.

Existe, ademÃ¡s un comando llamado {\bf shift} que permite eliminar el primer
parÃ¡metro de la lista, y correr todos los parÃ¡metros.  De tal manera que el
segundo parÃ¡metro pasa a ser \$1 y asÃ­. 

Veremos un ejemplo sencillo:

\begin{verbatim}
echo "Cantidad de parÃ¡metros: $#"
echo "Primer parÃ¡metro: $1"
shift
echo "Segundo parÃ¡metro $1"
shift
echo "El resto de los parÃ¡metros $*"
\end{verbatim}

El comando {\bf set} nos permite ver todas las variables de entorno.  Pero
ademÃ¡s, nos permite asignarle valor a los parÃ¡metros \$1, \$2, etc.  Por
ejemplo:

\begin{verbatim}
set Viva GNU Linux
echo "Primer parÃ¡metro: $1"
echo "Segundo parÃ¡metro: $2"
echo "Tercer parÃ¡metro: $3"
\end{verbatim}

\subsection{if}

Es la estructura que permite ejecutar los comandos solamente si se cumple
una determinada condiciÃ³n.  La sintaxis mÃ¡s usual:

\begin{tabular}{p{6cm}p{6cm}}
\begin{verbatim}
  if [ condiciÃ³n ]; then
    comandos
  else
    comandos
  fi
\end{verbatim}
&amp;
\begin{verbatim}
  if [ condiciÃ³n ]; then
    comandos
  fi
\end{verbatim}
\end{tabular}

En realidad, los corchetes \verb![  ]! son un comando en si mismo,
tambiÃ©n llamado \verb!test!,
por eso, para armar la condiciÃ³n utilizamos la sintaxis de test.
(para mÃ¡s informaciÃ³n: \verb!man test!). \\

Las condiciones serÃ¡n de este estilo: \\

\begin{tabular}{ll}
!condiciÃ³n &amp; Si condiciÃ³n es falsa \\
condiciÃ³n1 -a condiciÃ³n2 &amp; Las dos condiciones son verdaderas \\
condiciÃ³n1 -o condiciÃ³n2 &amp; Una de las dos condiciones es verdadera \\
cadena-de-caracteres &amp; La cadena no esta vacÃ­a \\
-z cadena-de-caracteres &amp; La cadena esta vacÃ­a \\
cadena = cadena &amp; Las dos cadenas son iguales \\
cadena != cadena &amp; Las cadenas son distintas \\
entero -eq entero &amp; Los enteros son iguales \\
\end{tabular}
\\

Por otro lado, tambiÃ©n podemos colocar otra cosa que no sea el comando test,
otros programas, que le devuelvan al if un cero o un uno, 
que el if luego interpretarÃ¡ como {\it false} o {\it true} respectivamente. 
O tambiÃ©n, la palabras {\bf true} y {\bf false}.

Realizaremos un script que escriba un mensaje si hay mÃ¡s de un
usuario conectado y otro diferente si hay sÃ³lo un usuario conectado.

\begin{verbatim}
cuantos=`who | wc -l`

if [ $cuantos -gt 1 ]; then 
        echo "Hay $cuantos usuarios conectados"
else
        echo "EstÃ¡s solo en el mundo"
fi
\end{verbatim}

En este script, primero guardamos la cantidad de usuarios conectados al sistema
en la variable {\bf cuantos}. Esto lo hacemos utilizando las comillas
invertidas, que son un recurso que nos provee el shell para utilizar la salida
de los comandos en nuestro cÃ³digo; cada bloque encerrado por las comillas
invertidas es reemplazado por la salida del comando en cuestiÃ³n. Otra forma de
hacer esto es utilizando una sintaxis alternativa a las comillas invertidas
\verb!$(...)!, esta forma tiene la ventaja que podemos anidarla fÃ¡cilmente.

Luego utilizamos la estructura de {\bf if} para compararlo con 1, la
opciÃ³n -gt del comando {\bf test} significa mayor que. \\

{\bf Recordar}: el comando [ normalmente es sinÃ³nimo del comando test.

\subsection{for}

Es una estructura que permite una iteraciÃ³n durante un nÃºmero 
determinado de veces.

La sintaxis:

\begin{verbatim}
  for variable in lista; do
    comandos
  done
\end{verbatim}

La variable, cuando se la coloca al lado del for, no lleva el signo \$ 
adelante, pero si en los comandos se hace referencia a ella, se debe 
escribir \$variable.

La {\it lista} puede ser:       

Una lista de nÃºmeros. Ej: 1 2 3 4

Una lista de archivos. Ej: *.java

Una lista de argumentos. Ej: \$* \\

Por ejemplo, si quisieramos hacer copias de varios archivos agregandoles una
extensiÃ³n, podriamos hacer.

\begin{verbatim}
for archivo in *; do
        cp "$archivo" "$archivo.bak"
done
\end{verbatim}

A continuaciÃ³n realizaremos un script que recibe por parÃ¡metro todos los
usuarios que queremos saludar y les manda un saludo a cada uno solamente si 
estÃ¡n conectados al sistema.

\begin{verbatim}
for i in $*; do
        if who | grep "^$i" &gt; /dev/null; then
                write $i &lt;&lt; EoT
Hola $i!
EoT
        fi
done
\end{verbatim}

Esta vez utilizamos la estructura {\bf for} para procesar los argumentos de 
nuestro comando. Para cada uno de los parÃ¡metros recibidos, verificamos si ese
usuario estÃ¡ conectado o no.  Para esto, abusamos un poco del if y 
demostramos que no es obligatorio usar test con el if. AquÃ­ utilizamos la
salida de un comando.

Si el usuario estÃ¡ conectado usamos el comando {\bf write} (que le manda un 
mensaje a la consola del usuario), para enviar un saludo a cada uno.

Para poder mandar el mensaje, utilizamos un meta-caracter de shell muy especial.
Este meta-caracter comienza con {\verb!&lt;&lt; EoT!}, y con esto le indica al shell
que la entrada de este comando es todo lo que ingresemos a continuaciÃ³n hasta la
que encuentre una lÃ­nea que solamente contenga la cadena {\verb!EoT!}.  

Esta cadena podrÃ­a ser cualquier otra, podrÃ­amos por ejemplo poner 
{\verb!&lt;&lt; blablabla!}, y luego deberÃ­amos terminar el texto con una lÃ­nea que
contenga {\verb!blablabla!}.

\subsection{while} 

Es una estructura que permite una iteraciÃ³n hasta que una determinada 
condiciÃ³n no se cumpla.

La sintaxis:
\begin{verbatim}
  while [  condiciÃ³n ]; do
    comandos
  done
\end{verbatim}

La condiciÃ³n es equivalente a la del if.

A continuaciÃ³n veremos otra manera de procesar los parÃ¡metros recibidos. 

\begin{verbatim}
while [ "$*" ]; do
        echo $*
        shift
done
\end{verbatim}

Este simple script imprime en cada lÃ­nea cada uno de los parÃ¡metros
recibidos. Vemos que si omitimos las \verb!" "! el comando test nos devuelve un error,
pues espera un solo parÃ¡metro. 

\subsection{case}

En casi todos los lenguajes de programaciÃ³n encontramos una estructura que nos
permite realizar distintas acciones segÃºn el valor de una determinada variable.

En el caso del shell esta estructura es {\bf case}.  Y se utiliza con la
siguiente sintaxis:

\begin{small}
\begin{verbatim}
        case $variable in
                     patron1)
                              comandos
                              ;;
                     patron2)
                              comandos
                              ;;
        esac
\end{verbatim}
\end{small}

El patrÃ³n con el que comprobamos al utilizar {\bf case} es similar al que
utiliza el shell (* para cualquier cadena, ? para cualquier caracter, [ ] para
rangos, $\backslash$ para escapar valores especiales y ' ' para escapar cadenas
completas), ademÃ¡s de un muy cÃ³modo {\verb!|!} para usarlo como o. \\

Para ver cÃ³mo es su funcionamiento, estudiaremos un ejemplo, en el que
utilizamos el comando {\bf cal}.  Este comando nos permite visualizar
calendarios.  Utilizado sin ninguna opciÃ³n nos muestra el mes actual.
Al agregar un nÃºmero a continuaciÃ³n (por ejemplo {\bf cal 2020}) nos muestra
el calendario de ese aÃ±o. Y si le pasamos dos parÃ¡metros (por ejemplo {\bf cal
11 2002}) nos muestra el calendario de ese mes y ese aÃ±o.

Este comando no entiende nombres de meses (enero, febrero, etc), y al ejecutar
{\bf cal 10} la salida serÃ¡ el calendario del aÃ±o 10, no del mes 10 del aÃ±o
actual, que es mÃ¡s probablemente nuestra expectativa.
El script que realizaremos permitirÃ¡ obtener un nuevo comando (ncal) que tenga
estas funcionalidades.

\begin{small}
\begin{verbatim}
# Analizamos los parÃ¡metros.
case $# in
   0) set `date`    # Si no vino ningÃºn parÃ¡metro,
      m=$2          # mostramos el calendario del mes actual
      y=$6          # y del aÃ±o actual.
   ;;
   1) m=$1          # Si vino un sÃ³lo parÃ¡metro,
      set `date`    # mostramos el calendario de ese mes
      y=$6          # y del aÃ±o actual.
   ;;
   2) m=$1          # Si vinieron dos parÃ¡metros,
      y=$2          # mostramos el calendario de ese mes y aÃ±o.
   ;;
esac

# Seleccionamos el mes que corresponde.
case $m in
   jan*|Jan*|ene*|Ene*) m=1 ;;
   feb*|Feb*)           m=2 ;;
   mar*|Mar*)           m=3 ;;
   apr*|Apr*|abr*|Abr*) m=4 ;;
   may*|May*)           m=5 ;;
   jun*|Jun*)           m=6 ;;
   jul*|Jul*)           m=7 ;;
   aug*|Aug*|ago*|Ago*) m=8 ;;
   sep*|Sep*)           m=9 ;;
   oct*|Oct*)           m=10 ;;
   nov*|Nov*)           m=11 ;;
   dec*|Dec*|dic*|Dic*) m=12 ;;
   [1-9]|10|11|12)      ;;          # El mes era numÃ©rico.
   *)                   y=$m; m=""; # SÃ³lo vino el aÃ±o.
esac

# Llamamos al calendario con el mes que elegimos.
cal $m $y
\end{verbatim}
\end{small}

Un uso muy frecuente del case de shell se encuentra en los {\it demonios}
de GNU/Linux.  Los demonios son los servicios que se ejecutan en el sistema
mÃ¡s allÃ¡ de quÃ© usuario es el que estÃ¡ loggeado.  Suelen existir scripts de
shell que se encargan de iniciarlos, detenerlos, reinciarlos, etc. 

\subsection{Funciones}

El shell nos provee de un manejo de funciones. Una funciÃ³n es un conjunto de
instrucciones encerradas en un bloque de cÃ³digo, una caja negra que hace
determinado trabajo.
Deben ser declaradas antes de poder llamarlas, y para llamarlas
alcanza con tipear su nombre.

\begin{small}
\begin{verbatim}
# declaraciÃ³n de funciÃ³n
funciÃ³n () {
        comandos
}
# declaracion alternativa.
function funcion {
        comandos
}

funciÃ³n # Llamado a funciÃ³n
\end{verbatim}
\end{small}

Las funciones reciben sus parÃ¡metros en \$1, \$2, \$*, etc. Y devuelven
valores entre 0 y 255, esto se consigue con la instrucciÃ³n de
shell {\bf return}.  El valor que devuelven puede ser accedido en el script
en la variable \$?.
Normalmente, las funciones acceden a variables globales, para poder usar locales
se debe usar la instrucciÃ³n de shell {\bf local}.

A continuaciÃ³n, algunos ejemplos que se proponen armar una calculadora en
shell.

\begin{small}
\begin{verbatim}
res=0; rem=0
add () {
        local i
        case $# in
        0)      res=0 ;;
        *)      res=$1
                shift
                for i in $*; do
                        let res+=$i
                done
                ;;
        esac
}
\end{verbatim}
\end{small}

Se trata de una funciÃ³n que suma todos los parÃ¡metros que recibe.  Si no
recibe ningÃºn parÃ¡metro el resultado es cero.
En cambio, si recibe algÃºn parÃ¡metro, inicializa la variable {\it
res} con el valor del primer parÃ¡metro, que luego borra de la lista de
parÃ¡metros con el comando {\bf shift}.  Y a continuaciÃ³n suma uno a uno,
todos los otros parÃ¡metros, utilizando el comando de shell {\bf let}, que
permite realizar operaciones aritmÃ©ticas simples.

AsÃ­ como la suma, podemos ver tambiÃ©n la multiplicaciÃ³n y la
divisiÃ³n.

\begin{small}
\begin{verbatim}
mul () {
        local i
        case $# in
        0)
                res=0
                ;;
        *)
                res=$1
                shift
                for i in $*; do
                        let res*=$i
                done
                ;;
        esac
}
div () {
        local i
        case $# in
        2)
                case $2 in
                0)
                        echo "Error: divisiÃ³n por cero";
                        res=0; rem=0
                        return 1
                ;;
                *)
                        let res=$1/$2
                        let rem=$1%$2
                ;;
                esac
        ;;
        *)
                res=0; rem=0
        ;;
        esac
}

add 3 255 123 123 30 29 4
mul $res 2 2
div $res 0
echo $res; echo $rem
\end{verbatim}
\end{small}

Existen aÃºn mÃ¡s capacidades para los scripts de shell, que no se explican
en este curso.  MÃ¡s informaciÃ³n puede encontrarse en la gran documentaciÃ³n
disponible en Internet, o leyendo el manual de bash.


\end{document}
</pre></body></html>