Contenido

  Introduccion (lo esta leyendo)

  1. Caracteristicas Del Sistema Operativo (S.O.) Linux
     1.1  Principales Caracteristicas
          1.1.1  Linux y los sistemas de Microsoft
          1.1.2  Linux y los sistemas de archivos
          1.1.3  Linux y las redes
          1.1.4  Linux y la interconeccion con otros sistemas
     1.2  Caracteristicas de Hardware requerido y soportado
          1.2.1  Hardware requerido por Linux en maquinas con arquitecturas
                 Intel 80x86
          1.2.2  Hardware soportado por Linux
  2. Estructura General Del Sistema De Archivos
     2.1  Sistema De Archivos
          2.1.1  Nombres de archivos
          2.1.2  Atributos de los archivos
          2.1.3  Directorios
          2.1.4  Estructura del sistema de archivos
          2.1.5  Rutas dentro del sistema de archivos
          2.1.6  Los "links" y los archivos
     2.2  Estructura General De Un Sistema De Archivos Linux
  3. Usuarios, Permisos y Grupos
     3.1  Permisos de acceso
     3.2  Directorio "home" y permisos predefinidos
  4. Dispositivos De Entrada-Salida
     4.1  Conceptos Fundamentales
          4.1.1  Puertos de entrada-salida
          4.1.2  Iterrupciones e IRQ's
          4.1.3  Accesos Directos a Memoria (DMA)
     4.2  Tratamiento de los dispositivos en Linux
          4.2.1  Archivos de los dispositivos mas comunes
  5. Programas y Procesos
     5.1  Ejecucion en primer plano y en "background"
     5.2  Demonios
  6. La Interaccion Con El Sistema. Shell y Comandos
     6.1  La Shell
          6.1.1  Funcionamiento de la shell
     6.2  Comandos
          6.2.1  Comandos simples
          6.2.2  Separador de comandos
     6.3  La Entrada Estandar y La Salida Estandar
          6.3.1  Redireccionando la salida
          6.3.2  Redireccionando la conexion de errores estandar
          6.3.3  Redireccionando la entrada
     6.4  Cañerias
     6.5  Generacion De Nombres De Archivos
  7. Comandos Y Utilidades
     7.1  Movimiento En El Sistema De Archivos
     7.2  Listado De Archivos
          7.2.1  Moviendo y copiando archivos
     7.3  Manipulando Archivos
          7.3.1  Moviendo y copiando archivos
          7.3.2  Realizando links
          7.3.3  Eliminando archivos
     7.4  Manipulando Directorios
          7.4.1  Creando directorios
          7.4.2  Eliminando directorios
     7.5  Busqueda De Archivos
          7.5.1  Ejemplos del uso de find
     7.6  Cambiando Permisos, Grupos y Dueños
          7.6.1  Averiguando los derechos de acceso de un archivo
          7.6.2  Cambiando los permisos
          7.6.3  Cambiando el dueño y el grupo de los archivos

 Empecemos con una pregunta clasica, ¿ Por que Linux y no otros S.O. ?

Existen una serie de problemas que son comunes a los sistemas operativos
comerciales y aquellos que, basicamente tienen las siguientes caracteristicas:

 * Cuestan mucho dinero (mas de U$S 50).
 * El codigo fuente del S.O. no esta disponible.
 * Existen limites extrictos en cuanto a la copia del sistema se refiere.

Consecuentemente, Windows, MacOS, DEC, Ultrix, Solaris, OS/2 son
sistemas operativos comerciales. Linux y FreeBSD son gratituos; estan
disponibles generalmente por el costo del medio (CD-ROOM, DISQUETTES,
ETC) en que se distribuye, el codigo fuente esta disponible y existen
pocas limitaciones en cuanto a su distribucion. Dado que los sistemas
operativos comerciales son la fuente de ingreso de las companias que
desarollan estos sistemas, se dan algunas situaciones que no son
ventajosas para el usuario final de la computadora. Algunos de estos
problemas se deben a la necesidad de proteger y mantener en secreto el
codigo fuente, como ser:

 * SE ACTUALIZA LENTAMENTE: Los S.O. comerciales como Windows, etc.
   realizan actualizaciones importantes cada 2 o 3 años (Windows 3.11,
   Windows 95, Windows 98 y proximamente Windows 2000), mientras que
   existen lanzamientos de las mayores distribuciones de Linux (Red
   Hat, Debian, SlackWare) cada 6 u 8 meses y se publica en Internet
   una version nueva del Kernel por semana, aproximadamente.

 * ALTO COSTO: Una copia y un numero limitado de licencias de cualquier
   sistema operativo comercial (especialmente para servidores) cuesta
   mas o menos U$S 400 dolares y casi nunca incluyen herramientas de
   desarrollo, como servidores de mail, de web, compiladores C, C++,
   etc.

 * SOPORTE TECNICO: Los compradores de S.O. comerciales dependen
   exclusivamente del servicio tecnico que brinda la compania en
   cuestion, incluso realizando costosas llamadas telefonicas. En la
   vereda de enfrente y de una forma descentralizada, existen una gran
   cantidad de puntos de consulta para Linux, ya sean organizaciones
   dedicadas o particulares experimentados.

Se agregan, ademas, un par de problemas que se aplican casi
exclusivamente al sistema Windows de Microsoft, veamos esto:

 * OBSOLENCIA DEL HARDWARE: No se mantiene compatible con los sistemas
   anteriores. Se dice que es tecnicamente posible "correr" Windows 95
   sobre una PC 386 a 25 Mhz, pero podemos comprobar que hacerlo sobre
   un harware anterior a una PC 486 DX2 a 66 Mhz con 16 Mb de Ram es un
   ejercicio masoquista :) Y es aca donde el costo aparece nuevamente
   como un factor importante a considerar.

 * PROPENSO A FALLOS: No es raro observar que Windows se "CAE" sin
   razon aparente, y la experiencia personal de quien alguan vez uso un
   Windows lo ha demostrado con creses. Aunque su hermano mayor,
   Windows NT, es bastante mas estable, todavia se caecon una
   frecuencia mayor a la que cualquier usuario espera. Hay casos
   documentados donde servidores Linux han estado operando por mas de 1
   año sin caida alguna :)

Caracteristicas de Linux

Ventajas

 * ADECUADO PARA LA COMUNICACION EN RED: Dado que Linux fue
   desarrollado por un grupo de programadores de Internet, se le dio
   una prioridad mayor a las propiedades de networking. Estas
   propiedades funcionan muy bien aun con configuraciones de hardware
   minimas. Se lo utiliza tanto de cliente como de servidor de otros
   S.O. populares; incluso puede ser utilizado por los proveedores de
   Internet. Soporta todos los protocolos mas utilizados (TCP/IP, FTP,
   Samba, Apple Talk, etc).

 * MULTIUSUARIO - MULTITAREA: Sigue la filosofia Unix, lo cual es
   ventajoso incluso si lo utiliza una sola persona, dado que las
   tareas se ejecutan con una proteccion mayor; ademas un mismo usuaro
   puede estar ejecutando varias tareas concurrentemente. Linux tiene
   la capacidad de manejar todo ese "trafico" de informacion.

Falencias

 * INTERFACE DE USUARIO INCONSISTENTE: GNU/Linux refelja el trafico de
   varios programadores, cada uno con metas de diseño diferentes,
   interfaces diferentes, etc. Incluso no existe una restriccion de
   consistencia entre utilidades de una misma distribucion. Esto puede
   llevar a confusiones y frustraciones. Actualmente, se estan llevando
   a cabo proyectos para promover interfases graficas consistentes a
   traves del sistema XWindows (KDE, GNOME, Teak, etc).

 * PAQUETES REPETIDOS: Dentro de una distribucion se pueden encontrar
   una gran cantidad de paquetes "repetidos"; cumplen uan misma
   funcion, pero fueron diseñadas por distintas personas, con objetivos
   de diseño. Por ejemplo: se pueden encontrar varios agentes de
   transmision de mail como el sendmail, smail, qmail, exim, etc.

 * FALTA DE APLICACIONES COMERCIALES: No se han desarrollado grandes
   suites de aplicaciones, aunque en Internet podemos encontrar el Star
   Office para Linux ;)

Conclusion

El numero de usuario de Linux esta creciendo rapidamente. Las ventajas
tecnicas de Linux por sobre otros S.O. comerciales son muy grandes,
importantes y evidentes. A pesar de ello, Linux todavia tiene
caracteristicas que lo hacen un poco dificil de usar y otras que pueden
hacer que Linux no sea el sistema adecuado al momento de elegir.

La mayoria de las personas que hoy son usuarios de Linux, eran usuarios
de los distintos sistemas de Microsoft (Windows, MS-DOS, etc) que se
dieron cuenta de la potencialidad del sistema Linux y de su gran
futuro. Hoy hay una gran tendencia a abandonar los sistemas de
Microsoft y sumarse a la filosofia del sistema operativo Linux. Pero,
cuidado, obviamente Linux no es el sistema ideal en todas las
situaciones. No existe tal cosa como la MEJOR COMPUTADORA o el mejor
SISTEMA OPERATIVO; todo va a depender de la tarea que realizemos. Por
eso, no creo que Linux sea la mejor solucion para todos, por mas que
sea tecnicamente superior a muchos S.O. comerciales.

Un usuario se beneficiara enormemente con Linux si lo que necesita es
software para programar :), utilizar Internet :), para procesar texto
con "TeX", y software tecnico en genereal, pero si se necesita
fuertemente el software comercial o si el usuario no se siente comodo
aprendiendo y tipeando comandos, entonces debe buscar en otro lado...

Bueno, bueno, hasta aca llego la introduccion ahora empezamos...


CAPITULO 1

CARACTERISTICA DEL SISTEMA OPERATIVO LINUX

En este capitulo vamos a describir las caracteristicas del S.O. Linux.
Es importante conocer estas caracteristicas ya que explican porque
Linux es un sistema tan potente, versatil y nos daran una amplia vision
de algunas de las caracteristicas internas importantes del sistema.
Tambien se describira el hardware sobre el cual se puede ejecutar Linux
y los distintos dispositivos de entrada/salida que son soportados por
el sistema.

Todo lo tratado en este capitulo es aplicable al sistema Linux sobre
plataformas de la familia Intel 80386 y superiores. El nucle analizado
es la version 2.2.5.

1.1 PRINCIPALES CARACTERISTICAS

Linux es un sistema operativo completo multiusuario con multitarea
real. Esto significa que sobre una misma maquina con el S.O. Linux
pueden estar trabajando varias personas simultaneamente y a su vez cada
persona puede estar ejecutando varios procesos.

Linux es un S.O. de 32 bits desarrollado para la plataforma Intel
80386. Fue realizado aprovechando las caracteristicas de modo protegido
de este procesador. Asi fue posible implementar la multitarea real y
otras caracteristicas como memoria virtual y ejecutables con carga de
paginas por demanda. Linux es tan robusto y completo que es capaz de
ser utilizado en maquinas en las universidades hasta en largas
corporaciones en las cuales trabajan cientos de personas al mismo
tiempo.

El codigo del nucleo de Linux fue realizado pensado en ser compatible
con los estandares de POXIS2 de Unix y otros. Esto quiere decir que es
totalmente compatible con la mayoria de los sistemas Unix comerciales y
gratituos que existen en la actualidad. De esta forma la mayoria del
software desarrollado para otras versiones de Unix funciona
perfectamente sobre Linux.

El nucle es capaz de emular por su cuenta las instrucciones del
coprocesador matematico 80387, con lo que cualquier maquina 80386 sin
coprocesador podra ejecutar, sobre Linux, aplicaciones que requieran de
estas instrucciones. En maquina 80486, no es necesario que el nucle
emule estas instrucciones ya que el coprocesador se encuentra instalado
en hardware como parte del procesador.

Otra caracteristica muy importante del sistema es la memoria virtual,
que permite que se puedan ejecutar programas que utilizan mas memoria
de la disponible y que es fundamentalmente necesaria para soportar la
multitarea. Ademas se soportan ejecutables con paginacion por demanda,
esto significa que solo las paginas necesarias son cargadas en memoria
en cada momento, utilizando asi mas efectivamente la memoria del
sistema. Relacionado con esto se encuentra el concepto de area de
intercambio o "SWAP" la cual se utiliza para almacenar temporariamente
informacion que no se puede matener en memoria porque esta no alcanza.
Esta area de intercambio es imprescindible en maquinas que tiene muy
poca memoria.

Fuertemente ligado a Linux, y a los sistemas Unix, esta el concepto de
librerias dinamicas. Estas se utilizan para almacenar codigo compartido
por varios programas en una unica libreria. Asi los programas son mas
chicos y utilizan estas funciones.

1.1.1 LINUX Y LOS SISTEMAS DE MICROSOFT

Cabe destacar que Linux NO ES COMPATIBLE con el sistema MS-DOS ni con
los sistemas Windows 95/98/NT. Los sistemas MS-DOS, Windows 95/98 son
sistemas hibridos de 16/32 bits y los programas que se ejecutan sobre
estos sistemas NO PUEDEN SER EJECUTADOS en Linux ya que fueron
desrrollados para ser ejecutados especificamente en esos sistemas. En
cuanto al sistema Windows NT es un sistema de 32 bits con un nucleo
completamente nuevo y tambien es totalmente incompatible con Linux. Sin
embargo, todos estos sistemas pueden convivir tranquilamente en una PC,
o sea que sobre cualquier computadora, con suficiente espacio en el
disco duro, es posible tener instalado Linux y ademas Ms-DOS, Windows
95/98 o NT.

Sobre Linux, existen emuladores de MS-DOS los que permiten que ciertas
aplicaciones de MS-DOS puedan ejecutarse sobre Linux. Uno de los
emuladores mas conocido es el llamado "DOSEMU" y permite ejecutar
aplicaciones como Turbo Pascal, Turbo Assembler, Harvard Graphics, etc.
A su vez existe un proyecto llamado "WINE" (Win Emulator) para permitir
ejecutar aplicaciones Windows sobre el sistema grafico de vantanas X
Windows.

1.1.2 LINUX Y LOS SISTEMAS DE ARCHIVOS

Linux posee un sistema de archivos propio, no compatible con los de
Microsoft, llamado "ext2fs" ( Extended File System 2 =). Esto quiere
decir que si en una PC tenemos instalados los sistemas Linux y
MS-DOS/Win95/98/NT desde los sistemas de Microsoft no podremos acceder,
ni para lectura ni para escritura, a los sistemas de archivos de Linux.

En cambio Linux es capaz de leer y escribir en sistemas de archivos de
MS-DOS (FAT), de Win95 (VFAT), inclusive con nonbres largos :)) , de
Win98 (FAT32), tambien con nombres largos =) , y de NT (NTFS). Aunque
el soporte de escritura sobre NTFS esta, hasta el momento, desarrollado
en forma experimental y se recomienda no utilizarlo ya que podria dañar
la escritura de archivos de una particion NTFS.

Ademas de los sistemas de archivos descriptos anteriormente, Linux es
capaz de leer y escribir sobre particiones basadas en sistemas de
archivos de MINIX, FFS (Fast File System), de Apple Macintosh, de los
sistemas Unix SCO, System V, Coherent y Xenix, y UFS de BSD (Unix de
Berkeley).

Linux es capaz de leer archivos de particiones OS/2 HPFS del S.O. OS/2
de IBM y del ADFS (Acorn Disk file System) del S.O. de Acorn. Soporta
ademas lectura desde los CD-ROM's sobre el sistema de archivos estandar
que es el ISO9660.

Ademas de esto podemos aplicar sobre el sistema de archivos ext2fs
porciones del disco limitadas a cada usuario. Esto es conocido como
"QUOTAS" y sirve para limitar la cantidad de espacio de espacio de
almacenamiento en disco que cada usuario es capaz de usar.

1.1.3 LINUX Y LAS REDES

Cuando hablamos de redes, Linux es la opcion. No solo porque el trabajo
en red esta altamente integrado con el sistema operativo, sino que
ademas una infinidad de aplicaciones de libre distribucion se
encuentran disponibles y que, mas importante aun, es totalmente robusto
bajo una gran carga, lo que es un resultado de años de desarrollo,
testeo y correccion basados en el proyecto Open Server.

Linux tiene realizada como parte de su nucleo una implementacion
completa de los protocolos de la famila TCP/IP muy eficiente y con
soporte para muchos conceptos avanzados de trabajo en redes.

Linux puede funcionar como servidor de WWW en Internet de forma
excelente. Es mas el servidor APACHE mediante el cual se puede instalar
un servidor WWW sobre Linux, es el servidor de WWW mas utilizado en
Internet y en Itranets actualmente. Ademas Linux es capaz de funcionar
como cliente de WWW, ya sea en una maquina conectada permanentemente a
Internet o mediante modem (PPP).

Esto no es lo unico que se puede realizar con un sistema Linux. Linux
es capaz de actuar de servidor PROXY, ser utilizado como FIREWALL, como
ROUTER avanzado o como BRIDGE (puente). Tiene soporte para alias de IP,
protocolos IPX/SPX, protocolos IPv6, AppleTalk, X.25, ISDN, PPP, SLIP,
PLIP, etc.

A nivel aplicaciones, Linux esta acompañado de innumerables
aplicaciones como lo son:

 * Sendmail: Puede actuar de servidor de mail, ya sea para enviar,
             recibir y realizar un sin numero de tareas relativas al
             correo electronico. Sendmail es el servidor de mail mas
             utilizado en Internet.

 * Ftp: Linux puede actuar como servidor o cliente de ftp (File
        Trasnfer Protocol). Un servidor de FTP es capaz de permitir que
        los clientes se conecten y recuperen archivos disponibles en el
        servidor.

 * Noticias (NEWS): Existen varias implementaciones del protocolo NNTP,
                    el cual sirve para permitir que una red de
                    computadoras sobre Internet intercambien articulos
                    que cubre todo tipo de topicos o tematicas.

 * DNS (Domain Name System): Un servidor DNS tiene el trabajo de
                             traducir los nombres utilizados en
                             Internet como por ejempl www.linux.org en
                             direcciones de IP. El trabajo de DNS sobre
                             Unix/Linux lo realiza un programa llamado
                             "NAMED".

 * Telnet: Telnet es un programa que permite a una persona usar una
           computadora remota como si estuviera trabajando directamente
           sobre la misma.

1.1.4 LINUX Y LA INTERCONECCION CON OTROS SISTEMAS

Linux puede interactuar completamente con varios sistemas conocidos
compartiendo archivos e impresoras en una red. Esto hace posible
integrar una maquina Linux con cualquiera de los sistemas mas
utilizados actualmente y permitir su total conectividad.

Los sistemas con los que Linux puede ser usado para compartir recursos
son los siguientes:

 * Apple: Linux soporta la familia de protocolos AppleTalk. Linux
          permite a clientes Macintosh ver recursos de un servidor
          Linux, asi como otros clientes Macintosh en una red y
          compartir archivos e impresoras desde el servidor Linux.

 * Entorno Windows: El grupo de aplicaciones SAMBA, que es provisto con
                    el S.O. Linux, permite interactuar a un sistema
                    Linux como servidor o cliente de maquinas con
                    Windows 95/98, Windows NT, DOS o Windows For
                    Workgroups.

 * Novell Netware: A traves del protocolo IPX, Linux puede ser
                   configurado para actuar como un servidor o un
                   cliente NCP, y permitiendo asi servicios de archivos
                   e impresoras en redes Novell.

 * Entornos Unix: La manera mas conocida y eficiente de compartir
                  archivos en entornos Unix es mediante NFS (Network
                  File Sharing). Este protocolo fue originalmente
                  desarrollado por Sun Microsystems. Es una de
                  compartir archivos entre maquinas de forma que
                  parezca que son archivos locales. Asi se puede tener
                  una maquina totalmente funcional sin necesidad de
                  tener un disco rigido instalado.

1.2 CARACTERISTICAS DE HARDWARE REQUERIDO Y SOPORTADO

1.2.1 HARDWARE REQUERIDO POR LINUX EN MAQUINAS CON ARQUITECTURA INTEL
80x86

Linux requiere como configuracion minimima de hardware una maquina con
procesador 80386 con 2 Mb de memoria RAM y 40 Mb de espacio libre en
disco rigido y puede correr tranquilamente sobre esta configuracion.
Para utilizar el modo grafico (vale la pena, Sistema X Windows ;)
necesita al menos 8 Mb de RAM y 100 Mb de espacio en disco.

Linux puede trabajar con los buses ISA, VLB (Vesa Local Bus), EISA y
PCI. Ademas puede trabajar en sistemas con arquitectura PS/2 MCA (Micro
Channel Architecture).

Linux puede correr, ademas, en la familia de PC's portables, desde las
80386 en adelante, inclusive con su sistema grafico.

1.2.2 HARDWARE SOPORTADO POR LINUX

PROCESADORES, UNIDADES DE PUNTO FLOTANTE Y MEMORIAS

Es totalmente compatible con los microprocesadores 386 SX / DX / SL /
DXL / SLC, 486 DX / SL / SX2 / DX2 / DX4 de Intel/AMD/Cyrix, Pentium,
Pentium MMX, Pentium Pro, Pentium II y III de Intel, K5, K6, K6-2 3D de
AMD, y todos los procesadores de la familia Cyrix.

Linux posee emulacion de unidad de punto flotante para servir de
soporte a los procesadores que no tiene coprocesador matematico como lo
son los 386 o los 486/SX.

Ademas una caracteristtica muy pontente de Linux es que se provee
soporte para sistemas con multiples CPU's (SMP).

Con respecto a las memorias, todas las memerias DRAM, FPM, EDO o SDRAM
pueden ser utilizadas con Linux.

CONTROLADORES DE UNIDADES DE DISCO RIGIDO, DISQUETTES, CD-ROM Y
UNIDADES DE CINTA

Linux puede trabajar con las controladoras estandar de disco IDE, MFM y
RLL. Tambien hay soporte para interfaces IDE extendidas (EIDE), con
hasta dos interfaces IDE y 4 discos y/o unidades de CD-ROM. Linux
detectara las siguientes interfaces EIDE:

 * CMD-640

 * DTC 2278D

 * FGI/Holtek HT-6560B

 * RZ1000

 * Triton I y II con Bus-Master DMA

Estas interfaces son las mas utilizadas en las computadoras personales
y en general Linux no tendra ningun problema en detectarlas.

Linux funcionara tambien con la interface mas moderna IDE/ATAPI, ya se
para discos, unidades de CD-ROM, unidades de discos flexible o unidades
de cinta.

Es posible, ademas, utilizar las modernas unidades Zip de Iomega, ya
sea por el puerto paralelo o SCSI.

UNIDADES DE CD-ROM (NO IDE) (NO SCSI)

Es factible (ja de donde salio esa palabra :) utilizar sobre Linux las
siguientes unidades de CD-ROM: Aztech, Creative Labs (una cagada),
Goldstar, IBM, Panasonic, Mitsumi, Sanyo, Sony, Teac.

ULTRA-DMA

Linux puede trabajar con las interfaces de disco con Ultra-DMA mas
conocidas del mercado. (Bus-Master, VIA, etc.).

SCSI

Linux soporta una gran cantidad de interfaces controladoras SCSI. Entre
las mas importantes encontramos: Adaptec, BusLogic, DTC, Future Domain,
NCR, Seagate, UltraStor, Quantum, Iomega y Western Digital.

ADAPTADORES DE RED

De forma similar, Linux soporta una amplia variedad de trajetas de red
Ethernet com lo son: 3Com, AMD, AT&T, Cabletron, DEC, Fujitsu, HP,
Intel EtherExpress, Novell NE2000/1000, SMC, Western Digital, Zenith.

Ademas soporta varias tarjetas de red ISDN, ARCNet, Token Ring, FDDI,
Amateur Radio, PCMCIA, Frame Relay, como otras intefaces (que no
utilizan tarjetas) SLIP, PPP o PLIP.

TARJETAS DE SONIDO

Las tarjetas de sonido mas importantes soportadas por Linux son las
siguientes: Adlib, Crystal, Ensoniq Soundscape, Gravis Ultrasound,
Logitech, Media TriX, Media Vision, Microsoft Sound System, OPTi, Sound
Blaster (100 % compatibles), Turtle Beach y puertos MIDI MPU-401.

MOUSES

Los siguientes mouses pueden ser utilizados con Linux:

 * Mouse serie de Microsoft

 * Mouse serial de Mouse Systems

 * Mouse de Logitech serie o de bus

 * Mouse de bus de Microsoft

 * Mouse ATI XL

 * Mouse PS/2

MODEMS

Todos los modems internos o externos (conectados a un puerto serie)
deben funcionar con Linux. Algunos frabricantes han creado lineas de
modems que solo funcionan con Windows 95, por lo que hay que tener
mucho cuidado al comprar, porque en Linux no sera posible hacerlos
funcionar.

Todos los modems que funcionan bajo interfaz PCMCIA deben funcionar en
Linux. En lo que respecta a los Modem/Fax, necesitan software apropiado
para funcionar, pero hay que asegurarse de que el Modem/Fax cumpla con
el estandar de Fax Clase 2.0 porque es generalmente verdad que el
software de Fax disponible para Unix no funciona com Modems/Fax de
Clase 1.0

IMPRESORAS

Todas las impresoras conectadas a un puerto paralelo funcionan en
Linux, pero al igual que los modems, algunos fabricantes han lanzado
impresoras designadas para trabajar solamente con el sistema Windows
95.

Muchos programas de Linux generan como salida de impresion documentos
en formato Postscript. En general este formato es entendido solo por
impresoras Laser y algunas otras impresoras avanzadas. Para solucionar
este problema en Linux podemos utilizar el programa Gostscript, que es
un interprete del formato Postscript para utilizar con las impresoras
que no tiene el soporte para este formato. Ghostscript posee, entre
otros, drivers para las siguientes impresoras:

 * Impresoras Apple

 * Cannon Bubble-Jet, LBP, LIPS III

 * Impresoras DEC

 * Epson 9 y 24 pines, y serie LQ.

 * Epson Stylus con color.

 * Una amplia variedad de las impresoras Hewlett Packard Deskjet,
   Paintjet y Laserjet
 * IBM, Oki, Okidata, Ricoh, Tektronix y Xerox

SCANNERS

Para trabajar con scanners en Linux se debe agregar el paquete SANE
(Scanner Access Now Easy), que es posible conseguirlo gratituamente en
Internet, y provee soporte para los siguientes scanners:

 * Adara ImageStar

 * Epson GT6000

 * Fujitsu SCSI-2 Scanners

 * Genius ColorPage, GS-B105G, GeniScan, GS-4000 y ScanMate

 * Varios HP ScanJet

 * Varios Logitech ScanMan

 * Nikon CoolScan

OTROS DISPOSITIVOS

Linux puede trabajar con Touch-Screens, Joysticks, Terminales en los
puetos serie, una gran variedad de trajetas de captura de video, varios
sistemas de manejo de energia UPS, etc.

DISPOSITIVOS PLUG & PLAY

PnP fue inventado por Intel y Microsoft, en parte por eso y en parte
por las diferencias que existian con los desarrolladores de Linux por
la forma en que se habia implementado, Linux no daba soporte a los
dispositivos PnP. Pero nos guste, o no, la mayoria del harware, hoy, es
PnP y Linux no tiene otra opcion que trabajar efectivamente con el PnP.

Los Kernels actuales de Linux poseen soporte integrado para PnP. Esto
favorece a la aceptacion de Linux porque muchas personas se rehusaban a
Linux porque los dispositivos PnP no funcionaban. Hoy estamos en
condiciones de usar cualquier dispositivo PnP con Linux, siempre que
sea 100% compatible con algun dispositivo soportado por Linux.



CAPITULO 2

ESTRUCUTURA GENERAL DEL SISTEMA DE ARCHIVOS

2.1 SISTEMA DE ARCHIVOS

La parte del sistema operativo que fija como los archivos son
estructurados, nombrados, accesidos, usados, protegidos e implementados
se conoce como "Sistema de Archivos".

Desde el punto de vista del usuario, el aspecto mas importante de un
sistema de archivos es la estructura que refleja el sistema de
archivos, que constituye un archivo, como los archivos se nombran y se
protegen, que operaciones estan permitidas sobre los archivos, etc.

2.1.1 NOMBRES DE ARCHIVOS

Las reglas exactas para nombrar archivos, varian de sistema en sistema.
En el caso de Unix es posible tener nombres de archivos de hasta 255
caracteres. Por lo tanto los siguientes nombres son totalmente validos:

 Tony, reporte, README.TXT, ls, cp, Resultados de la primera Fecha -
 Basket

Una caracteristica importante a tener en cuenta es que en Unix/Linux
cae en la categoria de sistemas que distinguen entre letras minusculas
y letras mayusculas, es decir que es "case-sensitive". Por lo tanto se
consideraran como archivos distintos los siguientes nombre:

 tony, Tony, TONY, tONY

Muchos sistemas operativos dividen el nombre de un archivo en dos
partes que se separan por un punto. La parte que se encuentra despues
del punto se llama "extension". En MS-DOS, por ejemplo, los nombres de
los archivos deben formarse con un nombre de 1 a 8 caracteres, con una
extension opcional de 1 a 3 caracteres. En Linux la extension es
opcional y puede tener la cantidad de caracteres que el usuario quiera.
Asimismo es posible definir archivos con dos o mas extensiones.
Ejemplos:

 README.linux, linux-2.2.5.tar.gz

En Linux no existe ninguna restriccion en las extensiones de los
archivos que implique la asociacion del mismo con ciertas operaciones.
En MS-DOS, por ejemplo, solo es posible ejecutar archivos con las
extensiones .BAT, .EXE, .COM. En Linux para poder ejecutar un archivo
se imponen otro tipo de restricciones que seran tratadas mas adelante.

Sin embargo, algunos programas o utilidades exigiran ciertas
extensiones en los archivos sobre los cuales se quiera trabajar. Por
ejemplo el compilador de C de distribucion libre que viene con las
distribuciones Linux, llamado gcc (GNU C Compiler), insistira en que
los archivos fuente tengan extension .c al final del nombre del
archivo. Hay que tener en cuenta que esto no es una restriccion
impuesta por el S.O. sino que es el programa el que exige este
tratamiento.

2.1.2 ATRIBUTOS DE LOS ARCHIVOS

Los principales atributos de los archivos en Linux tienen que ver con
sus permisos de acceso, su propietario, grupo al que pertenece (todos
estos conceptos se trataran mas adelante), su tamaño en bloques, y su
ultima fecha de modificacion.

En el sistema MS-DOS, los archivos ocultos se identificaban con un
atributo llamado HIDDEN. En Linux, en cambio, no existe ningun atributo
especial para determinar cuando un archivo es oculto. La distincion se
realiza sobre el nombre de archivo. Los nombres de los archivos que
comienzan con un punto son considerados archivos ocultos. Ejemplos:

 .Xclients, .bash_history, .emacs

2.1.3 DIRECTORIOS

Con respecto a los directorios y sus nombres y sus atributos, todo lo
dicho antes para los archivos se aplica de igual manera para los
directorios, ya que en Linux son a su vez archivos normales.

La estructura de directorios de la mayoria de los sistemas es una
estructura de arbol. Esto quiere decir que se tiene un directorio raiz,
el cual a su vez puede tener varios subdirectorios y asi sucesivamente.

Linux Fue desarrollado con el objetivo de ser multiusuario y de su alta
integracion en redes, por lo que uno de los objetivos fundamentales
fuel el hacer posible el trabajo en grupos y compartir informacion. Con
el modelo de directorios en forma de arbol es imposible permitir que se
comparta informacion entre varios usuarios, por eso Linux fue mas alla
y baso su sistema de archivos en la estructura de grafo aciclico
(FIGURA 2.1) que es una generalizacion natural del del esquema de
directorios jerarquico.

2.1.4. ESTRUCTURA DEL SISTEMA DE ARCHIVOS

En sistemas como MS-DOS las distintas unidades de disco, CD-ROM, disco
flexible, etc., se manipulan con una estructura de directorios propia.
Esto quiere decir que cada unidad tiene un directorio raiz y una
estructura de subdirectorios determinada. Para diferenciar las
distintas unidades se les asigna una letra a cada una de ellas. Asi
tenemos la unidad A, la unidad C, etc.

En Linux, esta estructura definitivamente no es adecuada porque trae
muchos problemas de mantenimiento. Mas aun, es totalmente inaplicable
en los sistemas de archivos de red como lo son NFS, SMB, etc. El hecho
de fijar a cada una de las unidades una letra que debe mantenerse para
siempre -o todos los programas perderan las refernecias de nombres- es
una limitacion muy grande en sistem tan flexible como Linux :)

2.1 SISTEMAS DE ARCHIVOS

                       ________________________
                       | Tony | Juan | README |
                       /-----------\-----------
                     \ / \ \-----\
       ____________/_________ _\_____________ \
       | mail | TODO | prog |       | prog | mail |     @
      /---------/------|----        -/---------\---
     /         /       |           /            \
    /        /      ___|__________/____________   \
   /       /       /   |         /             \    \
  /      /        |   _|________/___________    |     @
 @      @         |   | mod1 | mod2 | exec |    |
                  \_  ---|------|------|----   _/
                    \    |      |      |     _/ <-----_
                     \_  |      |      |   _/          |
                       \-|------|------|--/            Estos directorios
                         |      |      |               estan compartidos por
                         |      |      |               los usuarios Tony y
                         @      @      @               Juan.


FIGURA 2.1: ESTRUCTURA DE SISTEMA DE ARCHIVOS ACICLICA. EJEMPLO DE UN
            DIRECTORIO COMPARTIDO.

Para solucionar esto, Linux utiliza el concepto de particion raiz y
sistemas de archivos montados sobre la particion raiz. Esto significa
que todas las unidades utilizaran una estructura de directorios comun.
Asi no existiran varias unidades y una estructura de directorios por
unidad, sino que existira una unica estructura de directorios y sobre
ella se acomodaran las distintas unidades, inclusive las que se
comparten en redes.

La particion raiz es llamada "/" y es el directorio principal de la
estructura. Las unidades, antes de poder ser usadas, deben ser montadas
en el sistema de archivos. Para ello debe existir un "punto de montaje"
donde alojar la informacion de la unidad. Un punto de montaje no es mas
que un directorio cualquiera dentro del sistema de archivos, que debe
encontrarse vacio.

                       _______________________
                       / | mnt | Tony | README
                  |
                       °°/°°°°°°|°°°°°°°°°\°°
                       /         \          \______
                  ___/__         __\____________   \
                  |    |         | prog | mail |    @
                  °°°°°°         °°°°°°°°°°°°\°°
                                               \
                                                 \
                             ____________________  @
                            | mod1 | mod2 | exec |
                             °°|°°°°°°|°°°°°°|°°°
                               |      |      |
                               |      |      |
                               @      @      @

FIGURA 2.2: EJEMPLO DE MONTAJE DE UNA UNIDAD. ESTADO DEL SISTEMA DE ARCHIVOS
            PREVIO AL MONTAJE.

                       _______________________
                  /    | mnt | Tony | README |
                       °°/°°°°°°|°°°°°°°°°\°°
                       /         \          \______
       ______________/__         __\____________   \
       | part1 | part2 |         | prog | mail |    @
       °°°/°°°°°°°°/°°°°         °°°°°°°°°°°°\°°
        /        /                             \
      /        /                                 \
     @        @              ____________________  @
                            | mod1 | mod2 | exec |
                             °°|°°°°°°|°°°°°°|°°°
                               |      |      |
                               |      |      |
                               @      @      @

FIGURA 2.3: EJEMPLO DE MONTAJE DE UNA UNIDAD. ESTADO DEL SISTEMA UNA VEZ
            REALIZADO EL MONTAJE.

Veamos un ejemplo de montaje de una unidad en Linux. El estado del
sistema de archivos antes de montar la unidad es el que muestra la
figura 2.2. Supongamos que queremos montar un disquettes que posee dos
archivos llamados "part1" y "part2" en el punto de montaje dado por el
directorio "/mnt". El directorio esta vacio, por lo que no hay ningun
problema. El estado del sistema de archivos despues de realizar el
montaje se muestra en la figura 2.3.

Una vez que se monta la unidad dentro del sistema de archivos se puede
utilizar como si fuese cualquier directorio dentro de la estructura. La
unica diferencia es la forma en la que se accede a los datos, ya que un
directorio dentro del sistema de archivos puede corresponder a una
particion del disco rigido, un disquette, un CD-ROM o una unidad de red
que se encuentra en otra maquina. Afortunadamente, el sistema se
ocupara de tratar con el dispositivo que corresponda, de la forma
adecuada, para obtener y guardar la informacion. El tratamiento que
Linux aplica a cada directorio del sistema de archivos se realiza de
forma totalmente transparente para el usuario :)

Esta forma de tratar las unidades trae, por supuesto, muchas ventajas.
La belleza de los sistemas de archivos montados, por sobre las unidades
basadas en letras, recae en la transparencia. Uno puede agregar
unidades al sistema sin romper las referencias de las aplicaciones
existentes.

En el modelo de las unidades con letras, cada vez que se agregan
unidades al sistema, cambian las letras de las unidades. Asi la mayoria
del software y algunos S.O. se confunden cuando esto pasa. Tipicamente
se termina teniendo que reinstalar los programas cada vez que se mueve
algun disco de lugar. Este juego se vuelve ridiculo cuando se utilizan
unidades de red.

En Linux los sistemas de archivos de red, estan designados desde un
principio con el objetivo de la transparencia. Asi se pueden mover
archivos y aplicaciones de una maquina a otra en la red y ser
compartidos ya que sus puntos de montaje no tienen porque cambiar.

Lo que puede resultar incomodo es el hecho de tener que montar las
unidades antes de usarlas. Esto es verdad, pero solo con las unidades
extraibles (unidades de discos flexibles, o CD-ROM's), ya que las
unidades fijas (discos rigidos, unidades de red, etc.) se configuran
para que se monten automaticamente.

2.1.5 RUTAS DENTRO DEL SISTEMA DE ARCHIVOS

Las rutas (PATH) se utilizan para referirse a determinados directorios
o archivos dentro del sistema de archivos. Ya hablamos del directorio
raiz del sistema, el cual es llamado "/". Dentro de este se pueden
crear otros directorios y archivos. Por ejemplo, si creamos un archivo
llamado "Come As You Are.mp3" en el directorio raiz, entonces para
referirnos a el tenderemos que especificar la siguiente ruta: /Come As
you Are.mp3. Si creamos un directorio llamado "home" nos referiremos a
el como /home o /home/. Esto es posible porque es un directorio.

Generalizando, podemos encontrar encontrar un direcotorio llamado
"linux" que se encuentra dentro del directorio "src" que a su vez se
encuentra dentro del directorio "usr" que es un subdirectorio del
directorio raiz. La ruta adecuada sera: /usr/src/linux.

Las rutas no siempre se estructuran de esa manera. Todos los ejemplos
dados en el parrafo anterior corresponden a "rutas absolutas". Esto
quiere decir que son rutas completas, ya que marcan el camino desde el
directorio raiz hasta el archivo o directorio deseado. Tambien es
posible utilizar "rutas relativas". Las rutas relativas se construyen
dependiendo del punto en el sistema de archivos donde nos encontramos
ya que en cada momento nos encontramos en un cierto punto del sistema
de archivos (el directorio actual o el de trabajo) y podemos cambiar de
directorio, desplazandonos en la jerarquia. Toda ruta que comience con
una barra ("/") es considerada una ruta absoluta, toda otra ruta es
considerada ruta relativa.

                       _______________________
                  /    | mnt | Tony | README |
                       °°/°°°°°°|°°°°°°°°°\°°
                       /         \          \______
                     /           __\____________   \
                    @            | prog | mail |    @
                                 °°°°°°°°°°°°\°°
                                               \
                                                 \
                             ____________________  \
                            | mod1 | mod2 | exec |  _\_______________
                             °°|°°°°°°|°°°°°°|°°°   | mess | attach |
                               |      |      |      °°°|°°°°°°°|°°°°°
                               |      |      |         |       |
                               @      @      @         @       @


FIGURA 2.4: EJEMPLO DE RUTAS RELATIVAS. ARBOL DE DIRECTORIOS

Como ejemplo de rutas relativas consideremos la estructura del sistema
de archivos que muestra la figura 2.4, pueden darse las siguientes
situaciones:

 * Si nos encontramos en el directorio /, entonces la ruta
   Tony/mail/attach se refiere al archivo attach que se encuentra
   dentro del directorio mail que es un subdirectorio del directorio
   Tony. Facil :)

 * Si nos en el directorio /Tony/mail entonces las rutas ./attach y
   attach ambas se refieren al mismo archivo de los ejemplos
   anteriores. Tambien Facil :))

 * Si nos encontramos en el directorio Tony/prog, entonces la ruta
    ../mail/attach se refiere al mismo archivo que el ejemplo anterior.
    Un poco mas dificil :|

 * Si el directorio en el que nos encotramos es Tony/prog entonces la
   ruta ../../README se refiere al archivo README que se encuentra en
   el directorio raiza. Muy dificil ;(

HARD LINKS

Los "hard links" (links "duros") son links directos al inodo ( no
INODORO) del archivo y nos permiten tener mas de un archivo apuntando
al mismo inodo. Desde un punto de vista practico dos archivos con el
mismo inodo son el mismo archivo. Los cambios realizados sobre un
archivo seran reflejados en el otro y viceversa. Lo unico que hay que
tener en cuenta es que para borrar un archivo del sistema de archivos
hay que borrar todos los hard links que el mismo posea. Por ejemplo, si
el archivo doc1.tex es un hard link al archivo ejemplo1.tex, al borrar
el ultimo no estamos borrando el primero. Para borrar definitivamente
el archivo hay que borrar tambien el archivo doc1.tex. La unica
restriccion que poseen los hard links es que solo pueden definirse
dentro de un sistema de archivos, porque los inodos son unicos
internamente a un sistema de archivos.

Los directorios "." y ".." son hard links y estan presentes en todos
los directorios del sistema de archivos. El primero es un hard link al
mismo directorio y el segundo apunta al directorio padre. En particular
la entrada ".." en el directorio "/" apunta a si mismo; es decir que el
padre del directorio raiz es el mismo.

LINKS SIMBOLICOS

Los links simbolicos son otro tipo de links que tambien permiten darles
varios nombres a un archivo pero no asocian a los archivos por numeros
de inodo. Por esto los links simbolicos no tiene la restriccion de
tener que permanecer al mismo sistema de archivos y pueden referenciar
archivos entre sistemas de archivos. Esto quiere decir que un link
simbolico tiene su propio numero de inodo pero apunta a otro archivo.

Funcionalmente, los hard links y los links simbolicos son similares,
aunque tiene algunas diferencias. Por ejemplo, se pueden crear links
simbolicos a archivos que no existen, esto no es posible con los hard
links.

2.2 ESTRUCTURA GENERAL DE UN SISTEMA DE ARCHIVOS LINUX

En un sistema de archivos Linux encontraremos los siguientes
directorios importantes que forman parte del sistema y tiene funciones
particulares:

 /bin Archivos binarios o ejecutables. Aqui encontraremos los comandos
       mas utilizados. Los comandos que se encuentren en este
       directorio pueden ser ejecutados por todos los usuarios del
       sistema.

 /dev Archivos que representan los dispositivos del sistema.

 /etc Archivos de configuracion y pesonalizacion del sistema. Solo
       pueden ser modificados por el superusuario (ROOT).

 /sbin Ordenes ejecutables solo por el superusuario.

 /home Directorio donde se crean los directorios home de los usuarios
        del sistema.

 /lib Librerias escenciales del sistema.

 /proc Es una estructura virtual de archivos utilizada por el kernel
        para mostrar la informacion del sistema y su configuracion. A
        traves del mismo es posible ver la informacion de las
        interrupciones, puertos de entrada/salida, uso del CPU,
        memoria, particiones, modulos, asi como la informacion de cada
        proceso en particular y de los distintos dispositivos
        instalados en el sistema.

 /tmp Directorio que se utiliza como almacenamiento de archivos
 temporales.

 /var Informacion de la historia del sistema. Se guardan los mensajes
       que los precesos realizan al ejecutarse, informacion de debug,
       archivos a imprimir, mensajes de correo a ser distribuidos, etc.

 /boot Archivos e informacion necesaria para el arranque del sistema.

 /usr Programas, herramientas y utilidades instaladas en el sistema
       como extension del S.O.

 /usr/bin Binarios y ejecutables de los programas agregados al sistema.

 /usr/src Codigo fuente de los programas.

 /usr/src/linux Codigo fuente del kernel del sistema.

 /usr/man Manuales de los comandos del sistema y de los programas
 agregados.

 /usr/X11 Archivos del sistema de ventanas X Windows.

 /usr/X11/bin Archivos ejecutables del sistema de ventanas.

 /usr/local Softaware agregado localmente al S.O. En este directorio se
             suele instalar todo el software que agregamos luego de
             realizar la instalacion.



CAPITULO 3

USUARIOS, PERMISOS Y GRUPOS

El sistema operativo Linux es un sistema multiusuario. Esto quiere
decir que un numero cualquiera de personas pueden trabajar en el
sistema, ya sea de forma simultanea o no. Para comenzar a trabajar en
el sistema Linux es necesario iniciar una sesion, esto quiere decir que
el sistema nos preguntara el nombre de usuario con el cual queremos
iniciar la sesion. Este proceso se conoce como LOG IN.

Para que el sistema se asegure que la persona que intenta inciar una
sesion corresponde al usuario indicado se asocio una contraseña
(PASSWORD) con cada nombre de usuario. La contraseña solamente la debe
conocer el usuario propietario de la cuenta.

Como parte del proceso de inicio de sesion se debe ingresar la
contraseña apropiada, la cual sera encriptada por el sistema
inmediatamente y chequeada contra la base de datos de contraseñas y
gurdada en el sistema. Este proceso se conoce como autenticacion del
usuario. Si la contraseña es cheaqueada satisfactoriamente entonces el
usuario comienza su sesion en el sistema. De otra forma se rechaza la
solicitud de comienzo de sesion.

Para que este esquema de autenticacion funcione, es necesario que
exista una forma de crear cuentas de usuario y de asociarles sus
respectivas contraseñas, y ademas no se debe permitir a cualquier
usuario que pueda realizar estas tareas. Para solucionar estos y otros
problemas de seguridad, Linux posee una cuenta predefinida llamada
"root". Esta es la cuenta del superusuario, y es el unico usuario que
esta autorizado a crear cuentas, asignarles contraseñas y eliminarlas
si es necesario. Estos no son los unicos permisos que posee esta
cuenta; en realidad en una sesion iniciada como el superusuario, root,
es posible realizar todas las operaciones necesarias para la
administracion del sistema.

El esquema de autenticacion de usuarios es necesario pero no
suficiente. El hecho de que Linux utilice la estructura de un unico
sistema de archivos y de que sea un sistema multiusuario hacen que sea
indispensable un sistema de permisos aplicable sobre los usuarios para
con los archivos. Imaginemos un entorno en el cual no existieran
permisos sobre los archivos y existieran multiples usuarios. Facilmente
un usuario podria leer, modificar e incluso borrar archivos de otro
usuario, o podrian darse otras situaciones indeseables para con la
seguridad del sistema. Para evitar esto Linux establece un mecanismo de
proteccion de archivos que funciona mediante permisos y grupos.

Anteriormente, cuando hablamos de los atributos de un archivo,
mencionamos que un archivo tiene asociado un usuario y un grupo. Estos
atributos establecen quien es el usuario dueño del archivo y a que
grupo de usuarios pertenece. Los grupos son conjuntos de usuarios que
tambien son definidos por el superusuario como parte de la
administracion del sistema y sirven para agrupar a varios usuarios con
caracteristicas de acceso al sistema similares. El concepto de grupos
de usuario facilita enormemente la tarea de administrar los permisos en
sistemas con gran cantidad de usuarios.

3.1 PERMISOS DE ACCESO

Ademas de los atributos de usuario y grupo, un archivo tiene asociados
"permisos de acceso" que determinan las operaciones que son permitidas
sobre el mismo por parte de cada usuario. Los permisos de un archivo se
dividen en tres partes:

 * DUEÑO: El usuario que creo el archivo es el dueño del mismo. El
          dueño es determinado por el atributo del archivo que
          especifica quien es el dueño.

 * GRUPO: El conjunto de usuarios que comparten el archivo y necesitan
          permisos de acceso similares. El grupo sobre el cual recaen
          estos permisos es el grupo al cual pertenecen el archivo como
          lo determina el atributo de grupo.

 * OTROS (Universo): El universo se constituye de todos los demas
                     usuarios que no son ni dueños del archivo ni
                     pertenecen al grupo del archivo.

 Dentro de cada categoria, los permisos se dividen en tres grupos:
 leer, ecribir y ejecutar.

 PERMISO DE LECTURA: Deja a un usuario ver el contenido de un archivo
                     o, en el caso de los directorios poder listar su
                     contenido.

 PERMISO DE ESCRITURA: Permite escribir en los archivos o modificar su
                       contenido. En el caso de los directorios permite
                       crear nuevos archivos o borrar archivos del
                       directorio.

 PERMISO DE EJECUCION: Deja que el usuario pueda ejecutar el archivo,
                       ya sea como un programa o como un script de
                       comandos. El permiso de ejecucion sobre un
                       directorio nos permite cambiar el directorio de
                       trabajo.

Este mecanismo de permisos nos garantiza seguridad y simultaneamente
nos permite compartir archivos con grupos de usuarios. Pero para que
este esquema funcione adecuadamente, la pertenencia a los grupos debe
ser controlada rigidamente por el adminsitrador del sistema.

Los permisos asociados con un archivo dependen tambien de los permisos
que tenga asignado el directorio donde se encuentra el archivo. Por
ejeplo, si un usuario tiene permisos de lectura y escritura sobre un
archivo pero no tiene permiso de lectura ni de ejecucion sobre el
directorio en el cual se encuentra el archivo, entonces no podra leer
ni escribir el archivo. Generalizando, para poder acceder a un archivo
es necesario tener permiso de ejecucion en todos los directorios que
forman parte de la ruta del archivo, ademas del permiso adecuado sobre
el archivo.

3.2 DIRECTORIO "HOME" Y PERMISOS PREDEFINIDOS

Cuando el administrador del sistema crea una cuenta, crea ademas un
directorio, el cual sera propiedad del usuario que solicito la cuenta.
Este directorio es llamado "directorio home" y constituye el lugar en
el sistema de archivos donde el usuario puede guardar sus archivos. El
usuario tiene un control total sobre los permisos de su directorio
home. El acceso del usuario a otros directorios estara regido por los
permisos correspondientes. Cuando un usuario inicia una sesion en el
sistema, su directorio de trabajo es su directorio home.

Al crear un nuevo archivo o directorio, el sistema asigna una
combinacion de permisos predeterminada. Los permisos predefinidos para
los archivo son: de lectura y escritura para el dueño y de lectura y
ejecucion para el universo. Para los directorios son: de lectura,
escritura y ejecucion para el dueño y de lectura y ejecucion para el
grupo y para el universo (otros usuarios).

En cualquier momento, el usuario que es dueño del archivo o directorio
puede cambiar sus permisos para gestar la combinacion que desee.



CAPITULO 4

DISPOSITIVOS DE ENTRADA/SALIDA

4.1 CONCEPTOS FUNDAMENTALES

Los dispositivos de entrada/salida utilizados en las computadoras
pueden ser divididos, esencialmente, en dos categorias: dispositivos de
bloques y dispositivos de caracter.

Un dispositivo de bloque se caracteriza por guardar la informacion en
bloques de tamaño fijo, cada uno con su direccion. Los tamaños de
bloques mas comunes se encuentran en el rango de 512 bytes a 32768
bytes (32 Kb). La propiedad esencial de los dispositivos de bloque es
que es posible leer o escribir cada bloque independientemente de todos
los demas. Los "discos" son los dispositivos de bloque mas comunes.

El otro tipo de dispositivos de entrada/salida es el dispositivo de
caracter. Un dispositivo de caracter envia o acepta secuencias de
carateres sin relacion a una estructura de bloque. No tiene
direccionamiento y por lo tanto no tiene ninguna estructura mecanica
interna para realizar posicionamientos. Los siguientes dispositivos
pueden ser vistos como dispositivos de carater: impresoras, ratones,
interfaces de red, etc.

Este esquema de clasificacion no es perfecto. Algunos dispositivos son
dificiles de clasificar en estas categorias. Sin embargo, para fines
practicos esta clasificacion nos sera suficiente.

A continuacion se describen conceptos esenciales para el tratamiento y
configuracion de los dispositivos de entrada/salida. Estos conceptos
son importantes a la hora de instalar cualquier dispositivo sobre Linux
y determinan el exito o el fracaso de la instalacion y el correcto
funcionamiento del dispositivo.

4.1.1 PUERTOS DE ENTRADA/SALIDA

Asi como el sistema accede a memoria, tanto para lectura como
escritura, debe poder acceder a los dispositivos de entrada/salida. En
las maquinas basadas en las arquitecturas Intel 80x86 existe un espacio
de direccionado para la memoria y otro separado para los dispositivos.
Este esquema es conocido como espaciado separado de direcciones de
entrada/salida o espacio de entrada/ salida.

Los puertos de entrada/salida son direcciones mediante las cuales el
procesador se comunica con los dispositivos, ya sea leyendo datos o
escribiendolos. Un dispositivo puede tener asignadas una o mas
direcciones dentro del espacio, de acuerdo a cuantas necesite.

4.1.2 INTERRUPCIONES E IRQ'S

La velocidad con la que los dispositivos trabajan es, en general,
ordenes de magnitud mas lenta que la velocidad de proceso de la unidad
central de procesamiento (CPU). Cuando el CPU necesita comunicarse con
un dispositivo, inicia la operacion y, en vez de esperar a que el
dispositivo termine, sique realizando tareas, aprovechando el tiempo.
Asi el dispositivo debe poder comunicarle al CPU que la operacion de
entrada/salida finalizo o que necesita algun tipo de informacion para
continuar. Aqui es donde entran en juego las interrupciones.

Una interrupcion es una señal electronica que se emite desde un
dispositivo hacia el CPU para comunicarle informacion que permite
controlarlo. Para emitor las interrupciones existen lineas de pedido de
interrupcion (Interrupt ReQuest Lines) donde cada dispositivo situa los
pedidos de interrupcion.

Las arquitecturas Intel 80x86 proveen 15 lineas de interrupcion para
los dispositivos de entrada/salida. Cada dispositivo debe utilizar una
y solo una de estas lineas, porque sino existen altos riesgos de
conflictos en la atencion de las interrupciones.

 NOTA: Una caracteristica especial de la arquitectura de las IBM PC's
       es que algunos dispositivos trabajan con puertos de entrada
       salida e interrupciones prefijadas. Por ejemplo: el primer
       puerto serie, conocido como COM1, trabaja en el puerto 0x3f8.
       Otro ejeplo es la unidad de discos flexibles que trabaja sobre
       la linea de pedido de interrupcion numero 6.

4.1.3 ACCESOS DIRECTOS A MEMORIA (DMA)

Hay veces que los controladores de los dispositivos necesitan leer o
escribir grandes cantidades de datos desde o hacia la memoria del
sistema. En estos casos se utilzan los accesos directos a memoria
(Direct Memory Access). Estos sirven para permitir que los dispositivos
accedan directamente a memoria, pero esto se realiza bajo estricto
control del CPU.

4.2 TRATAMIENTO DE LOS DISPOSITIVOS EN LINUX

En los S.O. de la famila UNIX todos los dispositivos de entrada/salida
son tratados como archivos que forman parte del sistema de archivos. En
general estos archivos se encuentran en el directorio /dev, pero esto
puede depender del sistema.

Estos archivos, llamados "archivos de dispositivos", son creados por el
nucleo y son indespensables para el funcionamiento del sistema. Uno de
los principales objetivos es manejar los dispositivos como archivos es
que se abstrae y simplifica el tratamiento de los mismos para el
usuario. Los archivos especiales de dispositivos se manejan con las
mismas operaciones que se realizan sobre los archivos comunes, pero al
tratarse de un archivo de dispositivo el sistema se encarga de realizar
las tareas necesarias para comunicarse con el dispositivo. Esto se
realiza por medio de un "manejador de dispositivo" que forma parte del
nucleo y conoce los detalles de como tratar con el dispositivo en
cuestion.

Otra de las ventajas de este esquema de tratamiento de dispositivos es
que se pueden fijar permisos sobre los dispositivos utilizando el
esquema de usuarios, grupos y permisos ya analizado. De esta forma,
podremos hacer que un grupo de usuarios pueda usar una impresora, que
otro grupo pueda usar una red, o inclusive denegar el acceso a un disco
a un usuario determinado, etc.

Los archivos de dispositivos tienen un atributo especial que determina
si son archivos de dispositivos de bloque o de caracter. Esto es
necesario para que el sistema sepa como tratar a cada uno.

Como es posible que existan varios dispositivos de entrada/salida de
las mismas caracteristicas (podemos tener varios discos, varias placa
de red, etc.) se crean grupos de usuarios para cada clase de
dispositivo y hace que los archivos pertenezcan a esos grupos. Por
ejemplo: todos los dispositivos de disco del sistema son archivos que
pertenecen al grupo "disk, etc."

4.2.1 ARCHIVOS DE LOS DISPOSITIVOS MAS COMUNES

 * DISCOS MFM, RLL O IDE (EIDE): La interfaz IDE en Linux soporta hasta
   6 interfases con soporte para dos discos cada una. Se denominan
   primaria, secundaria, terciaria, etc. y a los discos se los denomina
   maestro y esclavo. Tenemos un maestro y un sclavo por cada interfaz.
   Sus nombres son:

      |°°°°°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°|
      | Interfaz              | Archivo de dispositivo |
      |-----------------------|------------------------|
      | Primaria - Maestro    |      /dev/hda          |
      | Primaria - Esclavo    |      /dev/hdb          |
      | Secundaria - Maestro  |      /dev/hdc          |
      | Secundaria - Esclavo  |      /dev/hdd          |
      | ...                   |      ...               |
      |_______________________|________________________|

       NOTA: Si uno de los lugares en las interfases es ocupado por un
             CD-ROM, se le asigna un archivo correspondiente a la
             interfaz, pero ademas se crea un link simbolico llamado
             /dev/cdrom que apunta a la interfaz que corresponda al
             CD-ROM.

 * DISCOS SCSI: Linux tiene soporte para 128 discos SCSI y sus archivos
 son:

        |°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°|
        | Numero de disco | Archivo de dispositivo |
        |-----------------|------------------------|
        | Disco SCSI 1    |     /dev/sda           |
        | Disco SCSI 2    |     /dev/sdb           |
        | ...             |     ...                |
        | Disco SCSI 26   |     /dev/sdz           |
        |-----------------|------------------------|
        | Disco SCSI 27   |     /dev/sdaa          |
        |-----------------|------------------------|
        | Disco SCSI 28   |     /dev/sdab          |
        |-----------------|------------------------|
        | ...             |     ...                |
        | Disco SCSI 128  |     /dev/sddx          |
        |_________________|________________________|

 * PARTICIONES: Cada disco puede estar particionado. Para referirnos a
   las particiones solo agregamos el numero de la particion
   correspondiente, al nombre del archivo que representa el disco. Los
   nombres se forman de la siguiente forma: /dev/hd?n y /dev/sd?n
   reemplazando por "?" la letra del disco adecuado y por "n" el numero
   de particion correspondiente.

       NOTA: En particiones del estilo MS-DOS (tipicamente usadas por
       Linux en sistemas i386) los numeros del 1 al 4 representan
       particiones primarias y del 5 en adelante particiones logicas.

 * UNIDADES DE DISQUETTES: Se soportan dos controladoras de unidades de
   disquettes con hasta 4 unidades por controladora.

           |°°°°°°°°°°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°|
           | Controladora - Disquettera | Archivo de dispositivo |
           |----------------------------|------------------------|
           | Controladora 1 - Unidad 1  |         /dev/fd0       |
           |       "        -   "    2  |         /dev/fd1       |
           |       "        -   "    3  |         /dev/fd2       |
           |       "        -   "    4  |         /dev/fd3       |
           |       "      2     "    1  |         /dev/fd4       |
           |       "      "     "    2  |         /dev/fd5       |
           |       "      "     "    3  |         /dev/fd6       |
           |       "      "     "    4  |         /dev/fd7       |
           |____________________________|________________________|

 * CONSOLAS VIRTUALES: Son 64 consolas y se nombran /dev/ttyn donde "n"
   es el numero de la consola virtual correspondiente.

 * PUERTOS SERIE, MODEMS Y MOUSES: Se tiene soporte para 64 puertos
   serie y se nombran como /dev/ttySn donde, de nuevo, "n" es el numero
   del puerto.

       NOTA: En sistemas basados en MS-DOS los puertos serie se nombran
       COM1, COM2, etc. La correspondencia de esos pueros con los de
       Linux es la siguiente:
            _______________________________
            |   MS-DOS    |   Linux        |
            |-------------|----------------|
            |  COM1       |   /dev/ttyS0   |
            |  COM2       |   /dev/ttyS1   |
            |  COM3       |   /dev/ttyS2   |
            |  COM4       |   /dev/ttyS3   |
            |_____________|________________|

   Los dispositivos de puertos serie pueden ser utilizados, entre otros
   dispositivos, por puertos serie fisicos o por modems. Si el modem es
   externo, entonces se conecta a uno de los puertos serie y se crea un
   link simbolico /dev/modem que apunte al puerto serie fisico
   correspondiente. Si el modem es interno entonces utilizara uno de
   los puertos que se encuentren disponibles (que no esten utilizados
   por puertos serie fisicos) y el link simbolico debera apuntar al
   puerto "logico" que se utilice.

   Si se utiliza un mouse serial entonces se crea un link simbolico
   /dev/mouse que apunta al puerto serie en cual esta conectado el
   mouse. Si no se utiliza un mouse serial entonces se pueden utilizar
   los siguientes dispositivos, dependiendo del tipo del mouse:

           |°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°|
           | Mouse                         | Archivo de dispositivo |
           |-------------------------------|------------------------|
           | Mouse PS/2                    |   /dev/psaux           |
           | Mouse Logitech de bus         |   /dev/logibm          |
           | Microsoft InPort mouse de bus |   /dev/inportbm        |
           | Ati XL mouse de bus           |   /dev/atibm           |
           | Mouse Atari                   |   /dev/atarimouse      |
           | Mouse Sun                     |   /dev/sunmouse        |
           | Mouse Amiga                   |   /dev/amigamouse      |
           |_______________________________|________________________|

 * PUERTOS PARALELOS: Pueden ser 3 y sus nombres son los siguientes:

         |°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°|
         | Puerto paralelo                | Archivo de dispositivo |
         |--------------------------------|------------------------|
         | Primer puerto paralelo (0x3BC) |       /dev/lp0         |
         |    "     "       "     (0x378) |       /dev/lp1         |
         |    "     "       "     (0x278) |       /dev/lp2         |
         |________________________________|________________________|

 * TECLADO: El teclado se maneja con el dispositivo /dev/kbd

 * PLACAS DE SONIDO: Los dispositivos relacionados con las placas de
   sonido son los siguientes:

   |°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°|
   | Dispositivo                                   | Archivo de dispositivo |
   |-----------------------------------------------|------------------------|
   | Control de mezcladora                         |     /dev/mixer         |
   | Secuenciador de audio                         |     /dev/sequencer     |
   | Puertos midi                                  |     /dev/midinn4       |
   | Audio digital                                 |     /dev/dsp5          |
   | Audio digital compatible con formato SUN      |     /dev/audio         |
   | Informacion del estado de la placa de sonidos |     /dev/sndstat       |
   |_______________________________________________|________________________|

 * JOYSTICK: Los dispositivos de joystick se nombran /dev/jsn, para los
   joysticks analogicos y /dev/djsn para los joysticks digitales; "n"
   es el numero de joystick.

 * INTERFASES DE RED: Las interfases de red mas utilizadas son las
   Punto a Punto (PPP) o las interfases Ethernet. Los dispositivos para
   las mismas son: /dev/pppn para las interfases PPP y /dev/ethn para
   las interfases Ethernet; "n" es el numero de interfase.

 * CD-ROM'S ESPECIALES:

       |°°°°°°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°°|
       | CD-ROM                 | Archivo de dispositivo  |
       |------------------------|-------------------------|
       | Sony CDU-31A/CDU-33A   |   /dev/sonycd           |
       | Sony CDU-535           |   /dev/cdu535           |
       | Goldstar               |   /dev/gscd             |
       | Optics                 |   /dev/optcd            |
       | Sanyo                  |   /dev/sjcd             |
       | Hitachi                |   /dev/hitcd            |
       | Mitsumi                |   /dev/mitcd            |
       | Panasonic/SoundBlaster |   /dev/sbpcdn6          |
       | Aztech                 |   /dev/aztcd            |
       |________________________|_________________________|




CAPITULO 5

PROGRAMAS Y PROCESOS

El concepto central mas importante en cualquier sistema multitarea es
el de proceso. Informalmente, un proceso es una abstraccion de un
programa en ejecucion. Un programa es una secuencia de instrucciones
que la computadora ejecuta con el objetivo de obtener un cierto
resultado; es lo que crea el programador. Cuando un programa no esta
siendo ejecutado se encuentra en un archivo del disco. Para poder
ejecutar el programa, una copia de las instrucciones debe ser cargada
en memoria. Cuando un programa se esta ejecutando, se lo llama proceso.
Es muy importante conocer las caracteristicas de los procesos para
comprender el funcionamiento de Linux y aprovechar la potencia de su
modelo multiprogramado.

Todas las computadoras modernas pueden hacer varias cosas al mismo
tiempo para aprovechar los recursos mas eficientemente. Por ejemplo: se
puede estar ejecutando un programa mientras se leen datos de un disco o
se imprime un documento. En un sistema multiprogramado, ademas, se
pueden estar ejecutando varios procesos al mismo tiempo (posiblemente
de distintos usuarios). Esto es posible gracias al concepto de
multiprogramacion. En un sistema multiprogramado, cada proceso obtiene
una tajada del tiempo del procesador. Estrictamente hablando, en cada
instante de tiempo el procesador ejecuta un solo proceso, pero en un
periodo determinado, digamos 1 segundo, puede trabajar sobre muchos
procesos dando a los usuarios la impresion de la existencia de
paralelismo. En realidad, como resultado de lo que realiza internamente
obtenemos un "pseudo-paralelismo" que hace que los procesos se puedan
ejecutar concurrentemente compartiendo el tiempo del procesador. Asi el
S.O. hace que la operacion de la computadora resulte mas productiva.

Linux es un sistema multitarea-multiusuario, lo que quiere decir que
cada usuario puede estar ejecutando varios procesos al mismo tiempo. El
S.O., atendera las necesidades de todos los usuarios de una manera
justa, ejecutando concurrentemente todos los procesos.

Cada vez que un usuario ejecuta un programa se inicia un proceso en el
sistema. Cada proceso tiene un PID (Process ID) unico, que es el numero
que sirve para identificarlo. Alguno se preguntara por que no es el
nombre del programa el que identifica al proceso ?. Bueno, esto trae
muchas desventajas, ya que por ejemplo, pueden haber varios procesos
ejecutandose como parte del mismo programa, y seria imposible
identificarlos. Sin embargo, cada proceso guarda como atributo el
comando que se ingreso para iniciarlo.

5.1 EJECUCION EN PRIMER PLANO Y EN "BACKGROUND"

Un proceso puede ejecutarse en primer plano o en "background". Solo
puede existir un proceso ejecutandose en primer plano y es el proceso
con el cual podemos interactuar. La entrada del proceso se toma del
teclado y la salida se muestra por pantalla. Los procesos que se
ejecutan en "background" no reciben entradas del teclado ni de ninguna
terminal, y en general se ejecutan "silenciosamente" sin necesidad de
interaccion.

Todos los S.O. proveen algun tipo de mecanismo para ejecutar procesos
en primer plano, pero, sin embargo no todos proveen la posibilidad de
ejecutar procesos en "background". La importancia de los procesos en
"background" se puede analizar considerando sus varias utilidades. Por
ejemplo: existen procesos que tardan mucho tiempo para completarse y no
requieren la interaccion del usuario. Compilar programas o comprimir un
archivo muy grande son ejemplos de este tipo de tareas. Estas conviene
realizarlas en "background", ya que mientras varios procesos se estan
ejecutando en "background" estamos libres para ejecutar cualquier otro
tipo de tarea.

Los procesos pueden estar en varios estados, los cuales pueden ser:

 * Ejecutando: El proceso ejecuta ya sea en primer plano o en
 "background"

 * Suspendido: Un proceso suspendido es un proceso que esta
   temporariamente detenido. Luego de suspender un proceso es posible
   reanudarlo ya sea en primer plano o en "background". De esta manera
   el proceso continua en el punto en el cual habia sido suspendido.

 * Interrumpido: A diferencia de un proceso suspendido, un proceso es
   interrumpido por algun evento y no puede ser reanudado. Por lo que
   es inmediatamente terminado.

5.2 DEMONIOS

Los demonios son procesos que se ejecutan en "background". Se los puede
pensar como procesos que se mantiene "dormidos" a la espera de eventos
que los despierten para llevar a cabo una tarea determinada. Cuando un
evento despierta un demonio, este se ocupa de ejecutar lo pertinente y
cuando completa el tratamiento del evento vuelve a dormirse y asi
sucesivamente. Los tipos de eventos que cada demonio espera y las
tareas que realiza en respuesta a los mismos dependen de la naturaleza
del demonio en cuestion. Las tareas mas comunes para las que se
utilizan demonios son: demonios que controlan dispositivos
(impresoras(lpd), adaptadores de red (pppd), etc.), control de los
protocolos de red (tcp/ip (tcpd), etc.), agentes de transferencia de
correo electronico (sendmail), etc.



CAPITULO 6

LA INTERACCION CON EL SISTEMA. SHELL Y COMANDOS

6.1 LA SHELL

Todo S.O. debe proveer un mecanismo para que el/los usuarios puedan
comunicarle lo que quieren realizar y para poder interactuar con el.
Linux posee una interfase de comunicacion llamada "shell" y es el medio
mediante el cual el usuario puede comunicarle comandos al sistema y
recibir la salida de los procesos con los que interactua.

Basicamente, la shell es un proceso mas que obviamente se ejecuta en
primer plano, ya que sino seria imposible interactuar con el mismo. Su
funcionamiento se limita a recibir comandos del usuario, interpretarlos
y ejecutar las tareas necesarias en respuesta a los mismos. El nombre
tecnico de la shell puede ser "interprete de comandos". Su funcion se
puede comparar a la del programa "comand.com" en MS-DOS que
esencialmente realiza las mismas tareas.

En los sistemas UNIX cada usuario puede elegir que shell quiere
utilizar para comunicarse con el sistema. Linux tiene varias shells las
cuales pueden ser elegidas por el usuario. Inclusive es posible que el
usuario programe y utilice su propia shell si asi lo desea. Las shells
que Linux provee son:

 * sh: Shell de Bourne. Es la shell mas utilizada en los sistemas UNIX.

 * csh: Shell de C. Es la shell preferida por los programadores. Es
        compatible con la shell de Bourne.

 * ash: Shell de Ash. Es una version especial reducida. Se utiliza
        cuando existe muy poca memoria disponible.

 * ksh - pdksh: Shell de Korn. Extension de la shell de Bourne.

 * bash: Bourne Again Shell. Es la shell de la FSF (Free Software
         Fundation). Amplia las capacidades de la shell de Bourne y es
         utilizada por Linux como shell predeterminada.

 * zsh: Z Shell. Compatible con la shell de Bourne.

6.1.1 FUNCIONAMIENTO DE LA SHELL

La shell es iniciada inmediatamente cuando un periodo de inicio de
sesion es autenticado exitosamente. El sistema recuerda cual es la
shell que utiliza cada usuario y carga la correspondiente al usuario
que inicio la sesion. Desde este momento, la shell muestra un
identificador llamado "prompt" que significa que esta esperando que el
usuario ingrese una orden.

Una vez que se visualiza el prompt, el usuario puede ingresar cualquier
orden, ya sea para que se ejecute en primer plano o en "background". Si
el pedido de ejecucion dado por el comando ingresado especifica que el
proceso se debe ejecutar en "background", el proceso se inicia y se
comienza a ejecutar en "background", por lo que el shell inmediatamente
vuelve a mostrar el prompt y al estado de espera de mas ordenes. Asi es
posible seguir ejecutando ordenes. Si el proceso se debia ejecutar en
primer plano, la shell no retorna el prompt hasta que el proceso
ejecutado se termine. Por lo tanto debemos esperar a que termine el
proceso para poder iniciar otro.

6.2 COMANDOS

   NOTA: Desde esta seccion en adelante todo lo referente a la shell y
   sus comandos estara basado en la shell bash (Bourne Again Shell) que
   es la shell predefinida en Linux :)

El uso interactivo tipico de la shell se basa en ingresar comandos
simples, comandos con calificadores, comandos con facilidades de
generacion de nombres de archivos, redireccion de entrada-salida, y
comandos combinados mediante el uso de "cañerias". Estas tecnicas son
poderosas y extremadamente utiles, pero son solo una parte de las
capacidades de la shell.

La shell es, ademas de interprete interactivo de comandos, un
interprete de un lenguaje de programacion de comandos llamado "El
lenguaje de programacion de la shell". Este lenguaje nos permite
realizar nos permite realizar "scripts" que sera posible ejecutar como
un programa binario mas, con la diferencia que lo interpreta la shell
linea por linea y ejecuta los comandos correspondientes. Mas adelante
nos ocuparemos de analizar este lenguaje de programacion en
profundidad, ya que es una de las caracteristicas mas poderosas de la
shell y nos sirve para automatizar muchas de las tareas que tenemos que
realizar en el sistema y nos ayuda a ahorrar la cantidad de comandos
que tenemos que tipear.

6.2.1 COMANDOS SIMPLES

Un comando simple es una secuencia de (una o mas) palabras separadas
por espacios o tabuladores. La primer palabra de la secuencia es el
nombre del comando. Las palabras subsiguientes son los argumentos del
comando. Los comandos mas simples son de una sola palabra.

Los comandos mas comunes pueden ser: ls para listar el contenido de un
directorio, ps para ver los procesos que se encuentran creados en el
sistema, reboot para reiniciar el sistema, etc.

ARGUMENTOS

Los comandos, en su forma mas simple, se ejecutan simplemente poniendo
el nombre del archivo correspondiente. Sin embrago, existen comandos
que necesitan argumentos para trabajar. Un ejemplo de esto puede ser el
comando cp que sirve para copiar archivos. Este comando necesita dos
argumentos obligatorios, el/los archivo fuente y el detino de la copia.
Por ejemplo:

 ==> cp /home/juan/cuotas.tex /home/tony/

Los argumentos se utilizan para pasar informacion adicional a los
programas que ejecutamos. En algunos casos son opcionales, en otros
obligatorios y puede ser que la cantidad de argumentos de algunos
comandos pueda ser variable. La gran mayoria de las veces los
argumentos seran nombres de archivos o de directorios, pero esto es
dependiente de cada programa.

El nombre del comando y sus argumentos deben ser separados por uno o
mas espacios, sino la shell nos informara del error con un mensaje.
Ejemplo:

 ==> ls/bin

 bash: ls/bin:  No such file or directory

Otros argumentos son los "modificadores" que son formas de pasar
opciones a los programas y seran tratados a continuacion.

MODIFICADORES

Los comandos, usualmente, sirven para realizar una funcion pero pueden
aceptar varias opciones que especifiquen como se debe realizar esta
tarea. Las opciones que cada comando acepta y la sintaxis con la que se
especifica la opcion dependen exclusivamente del comando en cuestion.
Aunque en general se puede hablar de "modificadores" que son la forma
general de ingresar las opciones a los comandos. Consideremos el
siguiente comando:

 ==> ls -a

Este comando listara el contenido del directorio actual, pero mostrara
ademas los que comienzan con ".", ya que estos son ocultos y al
ejecutar ls no son mostrados. Este comportamiento es especificado por
la opcion de mostrar los archivos ocultos que es seleccionada con el
modificador -a (all).

   NOTA: Un modificador muy util es -h que sirve para especificarle a
   un comando que nos muestre su sintaxis y las opciones que soporta.
   Esto sirve como referencia del funcionamiento del comando. Este
   modificador se puede usar con la mayoria de los comandos de Linux.
   Algunos comandos soportan --help o -help para la misma funcion.

6.2.2 SEPARADOR DE COMANDOS

Para ingresar varios comandos en una sola linea es necesario separarlos
por ";". Por ejemplo:

 ==> date;df -h

La salida de este comando sera la siguiente:

 Thu Apr 15 17:29:15 ART 1999
 Filesystem           Size  Used  Avail  Capacity Mounted on
 /dev/hda3            1.6G  613M   963M     39%   /
 /dev/hdc1            2.0G  1.9G   138M     93%   /akenaton
 /dev/hda2            298M  238M    60M     80%   /games
 /dev/hda1            2.0G  1.5G   546M     73%   /nt

La primera linea de la salida es generada por el comando date y muestra
la hora y el dia actual en el sistema. La tabla que es mostrada a
continuacion es generada por el comando df y muestra las capacidades,
tamaños utilizados y disponibles, y puntos de montaje de los distintos
sistemas de arhcivos que se encuentran montados. Notemos que las
unidades se muestran en distintos formatos de acuerdo al valor que
tenga cada campo. Esto es causado por la opcion -h que indica al
comando que muestre los valores con unidades significativas y no en
numero de bloques.

6.3 LA ENTRADA ESTANDAR Y LA SALIDA ESTANDAR

Los programas basados en el modelo de entrada/salida por teletipo son
aquellos en los que su salida consiste en lineas de texto ASCII. Estos
programas ofrecen solo una primitiva interfase con el usuario basada en
linea de comandos. Pero justamente por esto, y por la funcionalidad que
provee la shell, es posible interconectar varios programas que realizan
tareas simples para realizar tareas mas complejas. Todos los comandos
de Linux y la mayoria de sus utilidades se encuentran basados en este
modelo. Por esto es importante entender el funcionamiento e interaccion
de los programas, la shell y la entrada/salida para sacar provecho a
estas facilidades.

Cuando un programa, del modelo de teletipo, produce una salida sobre
una terminal el programa, en general, esta realizando operaciones de
salida a lo que se denomina salida estandar (stdout). Asimismo, cuando
tipeamos algo en el teclado de la terminal, un programa lee los
caracteres de lo que se llama entrada estandar (stdin). Para comunicar
errores y mensajes de diagnostico, existe una conexion de salida
separada llamada stderr.

La shell, por ejemplo, es un programa que lee caracteres de stdin e
interpreta los mismos como comandos, argumentos, etc. El comando ls
envia su salida (el contenido del directorio de trabajo) a stdout y
luego se visualiza en nuestra pantalla. Este funcionamiento es el
predefinido, ya que la entrada estandar y la salida estandar se
encuentran, normalmente, asociadas a la terminal de la computadora,
stdin el teclado y stdout a la pantalla.

La shell, sin embargo, nos permite reasignar o redireccionar las
conexiones de entrada, salida o la de diagnostico de errores. Esta es
una de las caracteristicas mas poderosas de Linux :)

6.3.1 REDIRECCIONANDO LA SALIDA

Supongamos que ejecutamos el comando ps (process status), el cual nos
reporta del estado de los procesos, que nosotros iniciamos, que se
estan ejecutando en el sistema. La figura 6.1a nos muestra la salida
generada por una ejecucion del comando ps. Asi visualizamos la salida
en nuestra pantalla.

Si nos interesa guardar la salida del comando ps, por ejemplo para
analizarla posteriormente, podemos hacer uso de la redireccion de la
salida que nos brinda la shell. Le indicamos a la shell que queremos
redireccionar la salida con el simbolo ">". Entonces, en nuestro
ejemplo, debermos ejecutar el comando como indica la figura 6.1b. En la
misma, observamos que el comando termina de ejecutarse sin realizar
ninguna salida en la pantalla, pues la salida del comando se envio al
archivo "procesos" y fue guardada en el mismo. Luego mostramos el
contenido del archivo procesos, con el comando cat, y visualizamos la
salida que el comando ps realizo al ejecutarse.

     NOTA: No es necesario que el archivo sobre el cual escribimos al
     redireccionar la salida exista antes de ejecutar el comando ya que
     la shell crea el archivo, si es necesario.

REDIRECCION NO-DESTRUCTIVA DE LA SALIDA

Al redireccionar la salida de un comando a un archivo se sobreescriben
completamente los contenidos del mismo. Hay ocasiones en las que no
queremos perder la informacion almacenada en un archivo, sino agregarle
datos al final del mismo. En el ejemplo de la figura 6.1b, los
contenidos del archivo procesos, si existia antes de ejecutarse el
comando, son sobreescritos. Para poder concatenar informacion en un
archivo usamos ">>" en vez de ">".

6.3.2 REDIRECCIONANDO LA CONEXION DE ERRORES ESTANDAR

La conexion de errores estandar es la segunda conexion de salida que el
S.O. Linux abre para cada programa. Normalmente es conectada a la
terminal, o sea a nuestra pantalla, y es por eso que cada vez que un
programa muestra un mensaje de error, este es visualizado en ella. Si
ejecutamos un comando y redireccionamos la salida del mismo a un
archivo, no estamos cambiando para nada la conexion de errores estandar
de ese comando, por lo que cualquier mensaje de error que el comando
reporte sera visualizado en pantalla. Esto ocurre porque la conexion de
errores estandar no se encuentra redireccionada. Hay programas que
producen una cantidad voluminosa de salida. En estos casos uno puede
querer redireccionar la conexion de errores estandar a un archivo, para
luego examinar los mensajes que el programa genero. Para redireccionar
la conexion de errores estandar se utiliza "2>". El numero 2 indica el
numero de conexion de salida que es justamente la conexion de errores
estandar.

6.3.3 REDIRECCIONANDO LA ENTRADA

Tambien es posible redireccionar la entrada. Ya vimos que uno de los
programas que lee la informacion de la entrada es la shell, los demas
programas que vimos (ls, ps, cat, etc.) producen su salida sin leer de
la entrada estandar. La shell lee los comandos a ejecutar de la entrada
estandar. Como la entrada estandar puede ser redireccionada a un
archivo, es posible que la shell obtenga los comandos a ejecutar desde
un archivo. Un ejemplo de esta situacion se muestra en la figura 6.2.
En la misma vemos que los contenidos del archivo "comandos" son los
nombres de dos comandos de Linux: date y ps. Luego utilizando el
simbolo "<" redireccionamos la entrada del programa bash (Bourne Again
Shell) al archivo comandos y los resultados se muestran en pantalla.

REDIRECCIONANDO LA SALIDA Y LA ENTRADA SIMULTANEAMENTE

Es posible redireccionar, simultaneamente, la entrada estandar y la
salida estandar. Cuando esto sucede, el unico rol que cumple la
terminal es ingresar el comando que vamos a ejecutar, pero luego el
programa trabaja sin tener asociada la entrada ni la salida a la
terminal. Salvo que no se redireccione la conexion de errores estandar
porque los mensajes de error serian visualizados en pantalla. La forma
de redireccionar la salida y la entrada simultaneamente se muestra con
un ejemplo en la figura 6.3.

6.4 CAÑERIAS: LA INTERCONEXION ENTRE PROGRAMAS

Las cañerias (pipes) conectan la salida estandar de un programa con la
entrada estandar de otro programa. Una cañeria es diferente a la
redireccion de la entrada/salida. Al redireccionar la entrada
conectamos la entrada de un programa a un archivo y al redireccionar la
salida conectamos la salida del programa a un archivo. Una cañeria
coencta la salida de un programa directamente con la entrada de otro
programa. Ver figura 6.4.

Para construir una cañeria debemos separar los comandos que queremos
conectar con el simbolo "|".

En el ejemplo de la figura 6.5, conectamos dos comandos: ls y wc. El
primero nos lista el contenido de un directorio, en este caso del
directorio /bin. El segundo comando, wc (word count) sirve para contar
palabras, lineas y caracteres, pero al pasarle la opcion -w le estamos
diciendo que solo cuente palabras. El funcionamiento de este pipe es
muy simple: El comando ls lee el contenido del directorio /bin y genera
una lista de palabras con los nombres de los archivos y directorios
encontrados. Esta lista, en vez de ser enviada a la terminal, es
redireccionada a la entrada estandar del comando wc que comienza a
contar las palabras y muestra el resultado en la salida estandar del
mismo que es la terminal.

6.5 GENERACION DE NOMBRES DE ARCHIVOS

El S.O. Linux nos permite especificar conjuntos de nombres de archivos
automaticamente utilizando "generacion de nombres de archivos y
caracteres comodines". Cuando ingresamos argumentos a un comando, la
shell examina los mismos con el objeto de detectar el uso de la
generacion de nombres de archivos. El usuario controla la generacion de
nombres de archivos especificando un modelo para los nombres de
archivo. La shell compara el modelo provisto con todos los archivos del
directorio de trabajo. Si alguno de los nombres de archivo responde al
modelo, entonces una lista ordenada alfabeticamente con todos los
nombres de archivos que responden al modelo es enviada al programa. Si
ninguno de los nombres de archivo del directorio actual cumple con el
modelo, entonces el modelo (en forma textual) es enviado al programa
como argumento. Un modelo consiste de caracteres ordinarios y de
"metacaracteres" llamados caracteres comodines. Los caracteres
ordinarios son interpretados textualmente; los metacaracteres tiene un
significado propio. Los metacaracteres utilizados para la generacion de
nombres de archivo y sus significados se muestran en la tabla 6.1.

 |°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°|
 | Metacaracter |          Significado                                     |
 |--------------|----------------------------------------------------------|
 |      *       | Equivale a cualquier cadena de caracteres                |
 |      ?       | Equivale a cualquier caracter                            |
 |      [       | Comienza una clase de caracteres                         |
 |      ]       | Termina una clase de caracteres                          |
 |      -       | Indica un rango de caracteres en una clase de caracteres |
 |______________|__________________________________________________________|

 Tabla 6.1: Metacaracteres utilizados para generacion de nombres de archivo.

El asterisco y el signo de pregunta son muy faciles de usar. Por
ejemplo *.c equivale a todos los archivos que tienen como sufijo .c
como pueden ser: prog.c, ab.c, Main.c; los siguientes nombres no
satisfacen el modelo unit2.cc, main.c.cc; el modelo ???.tex equivale a
todos los nombres de archivo que tengan tres caracteres cualesquiera y
luego el sufijo .tex, por ejemplo: ref.tex, cp1.tex, bea.tex, c++.tex,
cumplen con el modelo pero ab.tex, tony.tex, intro.tex chapter1.tex.z
no lo satisfacen.

Los corchetes y el signo menos se utilizan para formar modelos para
grupos de caracteres. Los caracteres en el grupo (o clase) son
especificados dentro de los corchetes. El modelo abc[aeiou] representa
todo nombre de archivo que comienze con abc y culmine con una unica
vocal. El signo menos se utiliza para especificar rangos de caracteres.
El modelo chapter[0-9] representa a todos los nombres de archivo que
comienzan con chapter y finalizan con un digito. Notemos que el rango
incluye a sus limites.

Es necesario realizar una aclaracion con respecto a los archivos
ocultos. Recordemos que todo archivo tal que su nombre comience con un
punto es considerado un archivo oculto. La generacion de nombres de
archivos no considerara que un modelo representa a un archivo oculto si
no se especifica explicitamente el punto al comienzo del modelo. Por
ejemplo: El modelo xinit* no representara al archivo cuyo nombre es
.xinitrc. Para solucionar esto es necesario especificar el modelo de la
siguiente forma .xinit*.

 # ps

   PID TTY STAT  TIME COMMAND
   338   1 S    0:00 /bin/login -- root
   356   1 S    0:00 -bash
   368   1 S    0:00 sh /usr/X11R6/bin/startx
   372   1 S    0:01 wmaker
   373   1 S    0:06 kfm
   377   1 S    0:00 wmmon
   381   1 S    0:00 mount.app
   394   1 S    0:37 emacs
   412  p0 S    0:01 kdvi apunte.dvi
   415   1 S    0:01 /usr/local/bin/x11amp
   479   1 S    0:00 kvt
   515  p0 R    0:00 ps

           a. Ejecucion del comando ps

 # ps > procesos

 # cat procesos
   PID TTY STAT  TIME COMMAND
   338   1 S    0:00 /bin/login -- root
   356   1 S    0:00 -bash
   368   1 S    0:00 sh /usr/X11R6/bin/startx
   372   1 S    0:01 wmaker
   373   1 S    0:06 kfm
   377   1 S    0:00 wmmon
   381   1 S    0:00 mount.app
   394   1 S    0:37 emacs
   412  p0 S    0:01 kdvi apunte.dvi
   415   1 S    0:01 /usr/local/bin/x11amp
   479   1 S    0:00 kvt
   515  p0 R    0:00 ps

           b. Ejecucion del comando ps redireccionando la salida al
              archivo "procesos"

           Figura 6.1: Redireccionando la salida del comando ps.

 # cat comandos
 date
 ps
 # bash < comandos
 Thu Apr 15 19:47:03 ART 1999
   PID TTY STAT  TIME COMMAND
   338   1 S    0:00 /bin/login -- root
   356   1 S    0:00 -bash
   368   1 S    0:00 sh /usr/X11R6/bin/startx
   372   1 S    0:01 wmaker
   373   1 S    0:06 kfm
   377   1 S    0:00 wmmon
   381   1 S    0:00 mount.app
   394   1 S    0:37 emacs
   412  p0 S    0:01 kdvi apunte.dvi
   415   1 S    0:01 /usr/local/bin/x11amp
   479   1 S    0:00 kvt
   515  p0 R    0:00 ps

           Figura 6.2: Redireccionando la entrada para que la shell
                       ejecute comandos desde un archivo.

 # cat comandos
 date
 pwd
 # bash < comandos > salida
 # cat salida
 Thu Apr 15 20:06:30 ART 1999
 /home/tony/docs/linux

           Figura 6.3: Redireccionando la entrada y la salida.



     |°°°°|__    <------------------------------------------------------\
 |---|____|  |_____                                                      |
 |    |      |     |            stderr                                   |
 |    |______|     | -----------------------------------> |°°°°°°°°|     |
 |         |       |                                      |        |     |
 |---------|       |                                 _--> |________|     |
    |  PROG1       |                                |        |   |       |
    |______________| --\                            |     /°°°°°°°°°\  --/
                        | stdout                    |    °°°°°°°°°°°°°
                        |                           |
                        |                           |
                        |                           |
                         \                          |
                         |                          |
     |°°°°|__            |                          |
 |---|____|  |_____      |                          |
 |    |      |     | <--/  stdin                    |
 |    |______|     |                                |
 |         |       |                                |
 |---------|       |                stdout & stderr |
    |  PROG2       |                                |
    |______________|  -----------------------------/

           Figura 6.4: Cañeria de dos programas.


 # ls /bin | wc -w
      75

           Figura 6.5: Ejemplo de una cañeria. Contar la acntidad de
                       archivos en un directorio.



CAPITULO 7

COMANDOS Y UTILIDADES

7.1 MOVIMIENTO EN EL SISTEMA DE ARCHIVOS

EL directorio actual, o el direcorio de trabajo, es probablemente la
pieza de informacion mas importante del entorno de trabajo. En
cualquier momento, podemos saber cual es el directorio actual
ejecurando el comando pwd (print working directory). La utilizacion de
este comando se muestra en la figura 7.1.

 # pwd
 /home/tony/txts/manual-linux

           Figura 7.1: Averiguando el directorio de trabajo.

Una vez que completamos el proceso de inicio de sesion (log in), nos
encontramos en el directorio home que el administrador del sistema nos
ha designado. Con el comando cd (change directory) podemos cambiar el
directorio de trabajo. Para ello tenemos que invocarlo con un
argumento: el directorio que queremos que sea el directorio de trabajo.
Se muestran ejemplos de este comando en la figura 7.2.

El argumento con el que proveemos al comando cd puede ser tanto una
ruta absoluta como una ruta relativa. En la figura 7.2a vemos un
ejemplo de una ruta relativa y en las figuras 7.2b y c vemos ejemplos
de argumentos de rutas relativas. Como caso especial, si ejecutamos el
comando cd sin parametros, el nuevo directorio de trabajo sera nuestro
direcotrio home.

7.2 LISTADO DE ARCHIVOS

7.2.1 LISTANDO ARCHIVOS

Como fue comentado anteriormente, el comado ls (list) se utiliza para
listar el contenido de los directorios. Este comando utiliza muchas
opciones, muchas de las cuales no vamos a tratar aqui. Nos vamos a
ocupar de su uso mas comun y de sus opciones mas utiles. El comando ls
acepta multiples argumentos. Cada argumento que le pasamos puede ser el
nombre de un archivo, de un directorio o una opcion (modificador). Si
no le pasamos ningun argumento, entonces nos mostrara el contenido del
directorio de trabajo. Por defecto, este comando nos muestra el
contenido de los directorios en forma de columnas con los nombres de
archivos encontrados como se muestra en la figura 7.3.

 # pwd
 /home/tony
 # cd /
 # pwd
 /

   a. Cambiando de directorio de trabajo de nuestro directorio home al
      directorio raiz.

 # pwd
 /
 # cd bin
 # pwd
 /bin

   b. Cambiando el directorio de trabajo a un subdirectorio.

 # pwd
 /home/tony/txts
 # cd ..
 # pwd
 /home/tony

   c. Cambiando el directorio de trabajo al directorio padre.

            Figura 7.2: Cambiando el directorio de trabajo.

 # ls
 init.d     rc.local     rc0.d      rc2.d     rc4.d     rc6.d
 rc         rc.sysinfo   rc1.d      rc3.d     rc5.d

            Figura 7.3: Listado del contenido de un directorio.

Como vemos, el listado se presenta en orden alfabetico. De esta forma,
la unica informacion que tenemos de cada archivo o directorio listado
es su nombre. Cuando queremos conocer informacion adicional de cada
archivo debemos usar los modificadores adecuados.

LISTADO EN FORMATO LARGO

El modificador -l indica al comando ls que visualize los nombres de los
archivos y directorios junto con otros atributos, mas especificamente
sus permisos, su dueño, el grupo al que pertenece, la cantidad de links
que posee, su tamaño (en bloques), y su fecha de modificacion. Un
ejemplo de un listado largo de archivos se muestra en la figura 7.4.

 # ls -l
 drwx------    2 root     root         1024 Mar 22 20:55 Xfree86/
 -rw-r--r--    1 root     root        25787 Apr  9 04:48 djetool-0.1.6.tar.gz
 -rw-r--r--    1 root     root       143078 Apr  9 04:50 hpdj-2.5.tar.gz
 -rw-r--r--    1 root     root       252411 Apr  9 04:11 kalendar-0.5b.tar.gz
 -rw-r--r--    1 root     root       677963 Apr  9 04:27 kget-0.6.1.tgz
 -rw-r--r--    1 root     root       766699 Apr  9 04:13 korganizer-1.1.tar.gz
 -rw-r--r--    1 root     root       288856 Apr  9 04:20 kpackage-1.2.tgz
 -rw-r--r--    1 root     root        92157 Apr  9 04:18 kuser-0.6.0.tar.gz
 -rw-r--r--    1 root     root      2643205 Apr  9 04:37 qt-1.42.tar.gz
 -rw-r--r--    1 root     root       140918 Apr  9 04:51 xtexcad-2.1.tar.z

     Figura 7.4: Listado en formato largo del contenido de un directorio

Sobre el ejemplo anterior se pueden notar varios puntos interesantes:

 * Cada archivo o directorio es mostrado en una linea separada
   acompañado de toda su informacion adicional.

 * La primer columna de la lista, la cual es una serie de simbolos,
   especifica que permisos posee el archivo, pero ademas nos muestra,
   mediante el primer caracter, el tipo del archivo. Los diferentes
   codigos que se utilizan se muestran en la tabla 7.1.

 * La primera entrada en la lista se diferencia de todas las demas
   porque el codigo de tipo de archivo es "d", lo que significa que es
   un directorio, mientras que todas las demas entradas muestran "-" lo
   que nos informa que son archivos ordinarios.

 * La columna siguiente especifica la cantidad de hard links que posee
   el archivo. En el caso del directorio Xfree86 vemos que posee 2
   mientras que los demas archivos todos tiene un solo link. El
   directorio posee 2 links porque uno es creado por el directorio en
   si mismo y el otro es la entrada que se nombra "." que todo
   directorio contiene y que apunta a si mismo. Cada directorio tiene
   ademas otra entrada denominada ".." que apunta a su padre. Esto
   quiere decir que si un directorio "dir" tiene 4 subdirectorios,
   entonces cada uno de estos poseera una entrada ".." que apuntara a
   "dir". Por lo tanto, el direcotrio "dir" tendra asociados 6 links:
   uno que represente al directorio, uno por la entrada "." dentro de
   el, y uno por cada subdirectorio que posea. Esta situacion se
   muestra en la figura 7.5.

 * Las siguientes columnas especifican el usuario que es dueño del
   archivo o directorio, y el grupo al que pertenece.

 * La columna que sigue nos muestra el tamaño del archivo, pero este
   tamaño es especificado en bloques. Esto es porque el S.O. utiliza
   bloques como la unidad de transferencia entre memoria y los
   dispositivos de bloques utilizados (discos rigidos, CD-ROM's,
   disketteras, etc). Tanto los archivos como los directorios pueden
   tener un numero cualquiera de bloques. En gral., en Linux, se
   utilizan bloques de 1KB o sea (1024 bytes), pero esto no siempre es
   verdad ya que pueden utilizarse tambien bloques de 512 bytes.

 * La siguiente columna nos muestra el momento en el que se modifico
   por ultima vez el archivo o el directorio.

   NOTA: Disculpen semjante dibujo, pero es que si lo hacia mas chico,
   mo se iba a entender demasiado ;)

                        _____ ______ ________
                       |     |      |        |
              /        | mnt | Tony | README |
                       |_____|______|________|
                                 \
                                 1 \
                                     \
             ________________________\|/___________________
            |         |         |        |        |        |
        /-->|    .    |  dir1   |  dir2  |  dir3  |  dir4  | <---------------------------\
       |    |_________|_________|________|________|________|                               \
     2 |       |         |  /|\        |    |   |   /|\  \                                   \
        \_____/          |   |         |    |    \    \    \                                   \
                         |   |         |     \     \    \    \__________________                 \
                        /    |         |       \     \    \ ______               \                 \  6
                      /      |          \        \     \           \ 5             \____             \
                    /         \           \        \     \_____      \_______            \             \
                  /         3 |             \      4 \         \              \           |             |
      __________\|/______     |    _______ _\|/____   |      __\|/__ _______   |       __\|/________    |
     |         |         |   /    |       |        |  |     |       |       |  |      |      |      |   |
 /-->|    .    |   ..    |--/  /->|   .   |   ..   |--/ /-->|   .   |  ..   |--/  /-->|  .   |  ..  |--/
|    |_________|_________|    |   |_______|________|   |    |_______|_______|    |    |______|______|
|       |                     |       |                |       |                 |      |
 \_____/                       \_____/                  \_____/                   \_____/

              Figura 7.5: Links definidos sobre un directorio.

            ______________________________________________
           | Codigo  | Significado                        |
           |°°°°°°°°°|°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°|
           |    -    | Archivo ordinario                  |
           |    d    | Directorio                         |
           |    c    | Archivo de dispositivo de caracter |
           |    b    | Archivo de dispositivo de bloque   |
           |    l    | Link simbolico                     |
           |    p    | Archivo de cañeria                 |
            °°°°°°°°° °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°

              Tabla 7.1: Codigos de tipos de archivos y sus significados.

LISTADO DE ARCHIVOS OCULTOS

Se pueden notar, en los ejemplos anteriores, que tanto el listado
predefinido como el listado largo producidos por el comando ls no nos
muestran los archivos ocultos, es decir aquellos que su nombre comienza
con un punto ".". Para listar los archivos ocultos es necesario
especificar la opcion -a. Un ejemplo de listado de archivos ocultos se
muestra en la figura 7.6.

LISTADO DE DIRECTORIOS

Hemos dicho que le podemos pasar varios argumentos al comando ls. Estos
argumentos pueden ser archivos o directorios. Supongamos que queremos
averiguar los permisos que tiene un archivo determinado. Para ello
ejecutamos:

 ==>  ls -l <archivo>

Como muestra la figura 7.7a. La ejecucion del comando tendra como
resultado una unica linea correspondiente al archivo solicitado y su
informacion correspondiente. Supongamos que, ahora, queremos averiguar
los permisos que tiene seteados un cierto directorio. Intuitivamente se
puede pensar que ejecutando ls -l <directorio> vamos a obtener la misma
informacion que obtuvimos con el archivo. Veamos la figura 7.7b cual es
el resultado. Imagino que adivinaron cual es el problema. En caso de
que no, piensen lo siguiente: el comado ls cuando recibe un argumento
decide si el mismo es un archivo o un directorio. En caso de ser un
archivo lista la informacion solicitada del mismo y en caso de ser un
directorio lista la informacion para cada archivo que se encuentre
dentro del direcotorio especificado. Para que el comando nos liste solo
la informacion del directorio y no de su contenido es necesario
especificar la opcion -d (directory). El comando quedara de la
siguiente forma:

 ==>  ls -dl <directorio>

  Ver figura 7.7c.

7.3 MANIPULANDO ARCHIVOS

Los comandos mv (move), cp (copy), ln (link) y rm (remove), junto con
ls son los comandos mas importantes a la hora de manipular los archivos
de Linux. Move y copy se utilizan para mover archivos de un lado a otro
en el sistema de archivos. La unica diferencia entre ellos es que move
borra el archivo original y copy no. El comando link se utiliza para
establecer pseudonimos a los archivos (links). Para borrar los archivos
utilizamos el comando remove.

7.3.1 MOVIENDO Y COPIANDO ARCHIVOS

El comando mv mueve un archivo de un sitio a otro. Si ambos sitios se
encuentran en el mismo sistema de archivos, entonces el movimiento es
esencialmente una operacion de renombre. Si por el contrario, los
sitios se encuentran en distintos sistemas de archivos entonces se
realiza una copia y luego se borra la original. La sintaxis del comando
mv es:

 ==>  mv [opciones] fuente..  destino

Donde las opciones son opcionales, valga la redundancia, y fuente...
significa que podemos especificar varios argumentos de fuente, pero
solo uno de destino.

Vemos varios ejemplos en la figura 7.8. En el primer ejemplo (figura
7.8a) utilizamos mv para cambiar el nombre de un archivo. En el ejemplo
siguiente (figura 7.8b) movemos un archivo de un directorio a otro y en
el ultimo ejemplo (figura 7.8c) movemos varios archivos.

 # ls -l penguinc06.gif
 -rw-r--r--   1 root    root       8994 Apr  9 04:42 penguinc06.gif

                     a. Listando la informacion de un archivo.

 # ls -l Xfree86/
 total 6756
 -rw-r--r--   1 root    root          21268 Mar 22 20:27 README
 -rw-r--r--   1 root    root         818655 Mar 22 21:04 XVG16.tgz
 -rw-r--r--   1 root    root        2587331 Mar 22 20:53 Xbin.tgz
 -rw-r--r--   1 root    root           3340 Mar 22 20:39 Xcfg.tgz
 -rw-r--r--   1 root    root         311690 Mar 22 20:34 Xdoc.tgz
 -rw-r--r--   1 root    root        1284484 Mar 22 20:50 Xfonts.tgz
 .
 .
 .

      b. Intento fallido de listado de informacion de un directorio.

 # ls -dl Xfree86/
 drwx------   2 root    root           1024 Mar 22 20:55 Xfree86/

       c. Intento exitoso.

       Figura 7.7: Listando direcotorios e informacion sobre direcotorios.

Para copiar archivos utilizamos el comando cp que se comporta de forma
similar a mv, pero con la salvedad de que no borra la fuente del
archivo original. Al igual que mv acpeta multiples argumentos siempre y
cuando el ultimo de ellos sea un directorio. En el ejemplo de la figura
7.9a realizamos una copia de un archivo en el directorio donde este se
encuentra; en el ejemplo de la figura 7.9b copiamos el mismo archivo
pero en otro directorio y en el utimo ejemplo (figura 7.9c) copiamos
varios archivos en un directorio.

COPIANDO DIRECTORIOS

Si necesita copiar un directorio en vez de archivos, debemos
especificar la opcion -R o -r (recursive) ya que sino el comando
omitira cada argumento fuente que sea un directorio y no sera copiado.
En caso de proveer esta opcion, todo argumento que corresponda a un
directorio sera copiado (incluyendo todos sus subdirectorios y los
subdirectorios de estos y etc) en el directorio destino especificado.
Veamos un ejemplo en le figura 7.10. Supongamos que queremos copiar el
directorio mail -que es subdirecotorio de Tony- completo con sus
archivos en el directorio /backup que se encuentra vacio. Para ello
ejecutamos:

 ==>  cp -r mail/ /backup/

 # ls
 kernel-2.1.125  kernel-2.2.1   kernel-2.2.5
 # mv kernel-2.2.5 kernel
 # ls
 kernel      kernel-2.1.125   kernel-2.2.1

    a. Utilizando mv para renombrar archivos

 # ls
 kernel      kernel-2.1.125  kernel-2.2.1
 # mv kernel ../config/
 # ls ../config/
 kernel
 # ls
 kernel-2.1.125  kernel-2.2.1

    b. Moviendo un archivo de un directorio a otro.

 # ls
 kernel-2.1.125  kernel-2.2.1   kernel-2.2.5
 # mv kernel* ../config/
 # ls ../config/
 kernel-2.1.125  kernel-2.2.1   kernel-2.2.5
 # ls

    c. Moviendo varios archivos de un directorio a otro.

        Figura 7.8: Moviendo archivos.

En la figura 7.10 se muestra el arbol resultante una vez realizada la
copia. El directorio que se copio se muestra resaltado con una elipse

7.3.2 REALIZANDO LINKS

Como vimos en la seccion 2.1.6 los "links" sirven para establecer
pseudonimos entre los archivos, es decir para que un mismo archivo
fisico sea referenciado por varios nombres logicos. En la terminologia
de Linux estos pseudonimos son llamados "links". Como tambien ya vimos,
existen dos tipos de links: hard links y links simbolicos. Primero
veremos los hard links y despues nos ocuparemos de los simbolicos.

El comando ln es el utilizado en Linux para establecer los links.

CREANDO Y MANIPULANDO HARD LINKS

Los hard links se crean con el comando ln. Supongamos que queremos
crear un link llamado index.htm a un archivo que se llama
presentacion.htm. El comando para realizar esto se muestra en la figura
7.11.

Una vez creado el hard link, tanto el viejo nombre del archivo
(presentacio.htm) como el nuevo (index.htm) se refieren al mismo
archivo, es decir a los mismos datos en la misma locacion fisica del
disco. Una vez creados los links, podemos ver los numeros de i-nodo
asociados a cada nombre de archivo ejecutando el comando siguiente:

  ==> ls -i

 # pwd
 /usr/local/articles/NT lies/
 # ls
 Lies.htm  lie10.jpg  lie3.jpg  lie5.jpg  lie7.jpg  lie9.jpg
 lie1.jpg  lie2.jpg   lie4.jpg  lie6.jpg  lie8.jpg
 # cp Lies.htm index.htm
 # ls
 Lies.htm  lie1.jpg  lie2.jpg  lie4.jpg  lie6.jpg  lie8.jpg
 index.htm lie10.jpg lie3.jpg  lie5.jpg  lie7.jpg  lie9.jpg

      a. Copiando un archivo sobre un mismo directorio.

 # ls
 Lies.htm  lie1.jpg  lie2.jpg  lie4.jpg  lie6.jpg  lie8.jpg
 index.htm lie10.jpg lie3.jpg  lie5.jpg  lie7.jpg  lie9.jpg
 # cp Lies.htm /root/articles/
 # ls /root/articles/
 Lies.htm

       b. Copiando un archivo hacia otro directorio.

 # ls
 Lies.htm  lie1.jpg  lie2.jpg  lie4.jpg  lie6.jpg  lie8.jpg
 index.htm lie10.jpg lie3.jpg  lie5.jpg  lie7.jpg  lie9.jpg
 # cp lie* /root/articles/
 # ls /root/articles/
 Lies.htm  lie10.jpg  lie3.jpg  lie5.jpg  lie7.jpg  lie9.jpg
 lie1.jpg  lie2.jpg   lie4.jpg  lie6.jpg  lie8.jpg

        c. Copiando varios archivos.

          Figura 7.9: Copiando archivos.

En la figura 7.11 vemos que tanto el archivo el archivo
presentacion.htm como el archivo index.htm poseen el mismo numero de
i-nodo, lo que quiere decir que ambos nombres se refieren al mismo
"archivo fisico". Esto se ilustra en la figura 7.12a. A partir de esto,
es valido acceder al archivo con cualquiera de los dos nombres que este
posee. Es importante notar que si modificamos el archivo
presentacion.htm, por lo dicho anteriormente, tambien modificamos el
archivo index.htm.

En la figura 7.11, antes de crear el hard link, listamos los detalles
del archivo presentacion.htm y vemos que el numero de links del mismo
es 1. Cuando listamos por segunada vez, luego de haber creado el hard
link, vemos que el numero de links de ambos archivos es 2. Ademas de
esto notemos que todos los atributos restantes son iguales, incluyendo
los permisos.

         _______________________
    /    | mnt | Tony | backup |
         °°/°°°°°°|°°°°°°°°°°°°°\              __________________
         /         \              \           /                  \
       /           __\____________  \        | ________            \______
      @            | prog | mail |    \------+-| mail |                   \
                   °°°°°°°°°°°°\°°           | °°°°°°°°\                    \
                                 \           |           \                    \
                                   \          \_______     \                   |
               ____________________  \                 \     \                 |
              | mod1 | mod2 | exec |  _\_______________ | _____\___________    |
               °°|°°°°°°|°°°°°°|°°°   | mess | attach | | | mess | attach |    |
                 |      |      |      °°°|°°°°°°°|°°°°° | °°°|°°°°°°°|°°°°°    |
                 |      |      |         |       |      |    |       |         |
                 @      @      @         @       @       \   @       @         |
                                                           \                   |
                                                             \________________/

  # ls mail/
  attach mess
  # cp -r mail /backup/
  # ls /backup/
  mail
  # ls /backup/mail/
  attach mess

               Figura 7.10: Copiando directorios recursivamente.

OBSERVACIONES ACERCA DE LOS HARD LINKS

Los hard links, como ya vimos, relacionan nombres de archivos con
numeros de i-nodo. Un sistema de archivos posee un cierto numero de
i-nodos con los cuales identifica los archivos que posee. Lo que quiere
decir que los i-nodos son relativos a un sistema de archivos particular
y que podemos tener dos archivos distintos que se encuentran en
distintos sistemas de archivos, pero con el mismo numero de i-nodo. Por
esto, no se pueden establecer hard links entre archivos que se
encuentren en distintos sistemas de archivos archivos. Esto es una
limitacion importante a la hora de utilizar hard links.

CREANDO Y MANIPULANDO LINKS SIMBOLICOS

Para crear links simbolicos tambien utilizamos el comando ln pero
modificamos su comportamiento con la opcion -s, la cual especifica que
el link a crear sera un link simbolico. En la figura 7.13 vemos como se
crearia un link simbolico index.htm al archivo presentacion.htm.

Al listar los contenidos del directorio, una vez creado el link
simbolico, vemos que la entrada del archivo index.htm nos informa que
el archivo es un link simbolico (atributo 1 en la columna de tipo de
archivo).

Ademas vemos que el numero de links del archivo presentacion.htm es 1,
esto es porque este numero cuenta la cantidad de hard links
establecidos y no se contabilizan los links simbolicos. Esto quiere
decir que al borrar el archivo presentacion.htm se borraran
directamente los contenidos, y el link simbolico quedara destruido, es
decir apuntara a algo que ya no existe.

  # ls -l
  total 60
  -r--------   1 root    root         59997 Apr 28 22:47 presentacion.htm
  # ln presentacion.htm index.htm
  # ls -l
  ls -l --color=none
  total 120
  -r--------   2 root    root         59997 Apr 28 22:47 index.htm
  -r--------   2 root    root         59997 Apr 28 22:47 presentacion.htm
  # ls -i
   262288 index.htm         262288 presentacion.htm

                   Figura 7.11: Estableciendo hard links.

Otra cosa para notar en el listado, es que la columna respectiva al
nombre de los archivos, vemos que el archivo index.htm apunta al
archivo presentacion.htm.

Es importante tener en cuenta que estos archivos son dos archivos
separados. Es decir que cada uno tiene sus atributos propios. Por
ejemplo, en la figura 7.13 vemos que los archivos tiene distintos
tamaños, distintas fechas de modificacion, etc.

Al realizar la consulta de los numeros de i-nodo de los archivos, vemos
tambien que ambos archivos tiene distinto numero de i-nodo, lo que
quiere decir que ambos tienen un lugar fisico distinto en el medio
donde se almacenan.

Anteriormente, vimos que no es posible crear hard links entre archivos
que se encuentran en distintos sistemas de archivos. Con los links
simbolicos, esto no es problema, ya que la asociacion se realiza por
nombre y no por numero de i-nodo. Ver figura 7.12b.

Al crear los links simbolicos, debemos tener cuidado con la forma en
que los creamos, ya que podemos hacerlo mediante una ruta relativa o
una ruta absoluta. Un problema que podemos tener si creamos un link con
una ruta relativa, es que si movemos el link a otro lugar del sistema
de archivos, perderemos la asociacion entre los archivos. Con los links
absolutos, esto no es problema.

  Observacion: Si borramos el archivo que es link simbolico, este sera
               eliminado pero no se borrara el archivo al cual apunta.
               Para borrar el archivo apuntado debemos borrar este
               directamente.

                           __________
                          |          |
                          |          |           _______
                          |          |          |       |
  index.htm -----------.  |          |   .----->|       |
                       |  |          |   |      |_______|
  presentacion.htm --. |  |          |   |
                     | °->|----------|___|       Archivo
                     °--->|__________|
                          |          |
                          |__________|

                        Tabla de i-nodos

    a. Un hard link entre los archivos presentacion.htm e index.htm.

                           __________
                          |          |
                          |          |           _______
   index.htm              |          |          |       |
      |                   |          |   .----->|       |
     \|/                  |          |   |      |_______|
  presentacion.htm --.    |          |   |
                     |    |----------|___|       Archivo
                     °--->|__________|
                          |          |
                          |__________|

                        Tabla de i-nodos

    b. Un link simbolico del archivo index.htm al archivo
    presentacion.htm.

      Figura 7.12: Estructura logica de los links entre archivos.

7.3.3 ELIMINANDO ARCHIVOS

Para eliminar archivos ordinarios, utilizamos el comando rm (remove).
Vemos un ejemplo en la figura 7.14. Debemos tener en cuenta que para
poder eliminar archivos debemos tener permiso de escritura en el
directorio donde se encuentren los archivos.

Si tenemos permiso de escritura sobre el archivo a borrar, entonces el
mismo sera borrado directamente. En cambio, si no tenemos permiso de
escritura sobre el archivo, entonces el comando nos preguntara si
queremos ignorar la proteccion y borrarlo igualmente. Si contestamos
"y" (yes), el archivo sera borrado, solo si somos dueño del mismo, sino
obtendremos un mensaje que nos indicara que no tenemos permiso para
borrar el archivo. Esto es ilustrado en la figura 7.14: el archivo
vi.htm tiene permiso de escritura, por lo que es borrado
inmediatamente. En cambio el archivo persentacion.htm no tiene seteado
el permiso de escritura, por lo que el comando nos preguntara si
queremos ignorar la proteccion. Contestamos que si y el archivo es
eliminado.

Se debe tener mucho cuidado cuando eliminamos archivo en Linux, ya que
los archivos eliminados realmente SE PIERDEN Y NO HAY FORMA DE
RECUPERARLOS. No existe ningun mecanismo de recuperacion de archivos en
Linux. Siempre que estemos en duda de borrar un archivo, pensemos en
preservarlo ya que no tendremos forma de recuperarlo.

OPCIONES DEL COMANDO RM

Las opciones mas importantes del comando rm son las siguientes:

 * -f: Forzar la eliminacion de los archivos sin permiso de escritura
       sin pedir la confirmacion.

 * -i: Operacion interactiva. Realizar una confirmacion antes de
       eliminar cada archivo. Las respuestas que comienzan con y o Y
       son consideradas afirmativas.

 * -r: Operacion recursiva. Elimina archivos y subdirectorios, borrando
       todo un subarbol de directorios.

 # ls
 presentacion.htm
 # ls -s presentacio.htm index.htm
 # ls -l
 total 60
 lrwxrwxrwx  1 root    root            16 Apr 29 19:11 index.htm -> presentacion.htm
 -r--------  1 root    root         59997 Apr 28 22:47 presentacion.htm
 # ls -i
  262269 index.htm       262269 presentacion.htm

                 Figura 7.13: Estableciendo links simbolicos.

 # ls -l
 total 14
 -rw-r--r--  1 gg      users        7559 May  2 01:15 commands.htm
 -r--------  1 gg      users        2880 May  2 01:15 presentacion.htm
 -rw-r--r--  1 gg      users        2880 May  2 01:15 vi.htm
 # rm vi.htm
 # rm presentacion.htm
 rm: remove 'presentacion.htm', overriding mode 0400? y
 # ls
 commands.htm

                 Figura 7.14: Eliminando archivos.

7.4 MANIPULANDO DIRECTORIOS

7.4.1 CREANDO DIRECTORIOS

Para organizar nuestros archivos utilizamos directorios y
subdirectorios. La creacion de directorios tambien se realiza mediante
comandos. El comando para crear directorios es mkdir (make directory).
El mismo acepta una lista de argumentos (cada argumento puede ser una
rura absoluta o una rura relativa) y crea un directorio por cada
argumento que se encuentre en la lista. Los directorios, una vez
creados, se encuentran vacios.

Veamos un ejemplo en la figura 7.15. primero creamos un directorio
llamado qt, verificamos que haya sido creado y vemos que esta vacio.
Luego creamos tres directorios juntos (c, java. c++).

   # la
   # mkdir qt
   # ls
   qt
   # ls qt
   # mkdir c java c++
   # ls
   c     c++    java    qt

     Figura 7.15: Creando directorios.

7.4.2 ELIMINANDO DIRECTORIOS

Tenemos dos formas de eliminar directorios:

 1. Utilizando el comando rm con la opcion -r (recursive). Esto borrara
    un directorio junto a todo su contenido (archivos y subdirectorios)
    eliminando asi todo un subarbol.

 2. Utilizando el comando rmdir (remove directory). Este comando nos
    permite eliminar directorios pero con la exigencia de que los
    mismos esten vacios. Si queremos borrar un directorio que tiene
    archivos dentro, debemos, primero, eliminar los mismo com rm y
    luego eliminar el directorio con rmdir.

Ilustramos ambas formas en la figura 7.16. En la figura 7.16a, borramos
el directorio com rm -r y en la figura 7.16b lo hacemos con rmdir.
Notemos, en el primer caso, que el comando nos pide confirmacion para
cada archivo o directorio que se encuentre en el directorio a borrar.
Esto se puede evitar utilizando rm -rf, ya que la opcion -f (force),
hace que no se realicen las confirmaciones y borra directamente.

En el segundo caso, primero debemos vaciar el directorio (en este caso
lo hacemos con rm -f) y luego debemos eliminar el directorio con rmdir.

7.5 BUSQUEDA DE ARCHIVOS

En ocasiones podemos estar interesados en averiguar donde se encuentran
determinados archivos. Cuando queremos buscar uno o mas archivos dentro
de un directorio en particular, podemos utilizar el comando ls para
listar los archivos y verificar en la lista si el/los mismos se
encuentran alli. Pero cuando queremos buscar archivos en todo un
subarbol de directorios, trabajar con ls puede resultar muy incomodo.

El comandp find (buscar), localiza archivos, de acuerdo a un criterio
de busqueda, en todo un subarbol de directorios y nos reporta los
resultados.

Los criterios de busqueda del comando find se pueden ser combinar para
realizar busquedas realmente complejas. Aqui vamos a estudiar los
criterios mas utilizados a nivel usuario que a su vez son los mas
sencillos.

La sintaxis del commando find es la siguiente:

 ==> find <path...> <criterio>

  * <path...> es una lista de directorios donde se comenzara a buscar.
    find buscara en los subarboles que comienzan en cada directorio
    especificado en la lista de directorios.

  * <criterio> es una serie de acciones, tests y opciones que
    especifican un cierto criterio de busqueda y posiblemente ciertas
    acciones a realizar sobre los archivos encontrados. Esto se vera
    mas adelante.

   # ls
   c    c++    java    qt
   # ls java
   hello-world.class  hello-world.java
   # rm -r java
   rm:descend directory 'java'? y
   rm: remove 'java/hello-world.java'? y
   rm: remove 'java/hello-world.class'? y
   rm: remove directory 'java' y
   # ls
   c    c++    qt

              a. Eliminando un directorio con rm -r.

   # ls
   c    c++    java    qt
   # ls java
   hello-world.class  hello-world.java
   # rmdir java
   rmdir: java: Directory not empty
   # rm -f java/*
   # rmdir java
   # ls
   c    c++    qt

              b. Eliminando un directorio con rmdir.

                Figura 7.16: Eliminando directorios

No vamos a analizar detalladamente la sintaxis de la expresion que
denota los criterios de busqueda, sino que vamos a ilustrar el uso del
comando find con varios criterios de busqueda tipicos.

7.5.1 EJEMPLOS DEL USO DE FIND

BUSCANDO ARCHIVOS POR NOMBRE

Supongamos que queremos buscar todos los archivos que comiencen con X
en el subarbol que encabeza el directorio /etc. El comando utilizado
para realizar la busqueda y el resultado de la misma se muestran en la
figura 7.17.

En este ejemplo, para realizar la busqueda, le pasamos como ruta de
comienzo el directorio /etc y la expresion que especifica que el
criterio es -name X*. La opcion -name especifica al comando find que
queremos realizar la busqueda por nombre de archivo y el argumento X*
expresa que queremos buscar los archivos cuyo nombres comiencen con X.

En general, la busqueda de archivos por nombre se realiza con el
siguiente comando:

 ==>  find <path> -name <expresion>

Donde la expresion especifica el formato de los nombres a buscar. Para
formar la expresion podemos utilizar todas las capacidades de
generacion de nombres de archivo que nos prove la shell (ver seccion
6.5).

 # find /etc -name X*
 /etc/X11
 /etc/X11/xinit/Xclients
 /etc/X11/xdm/Xaccess
 /etc/X11/xdm/Xresources
 /etc/X11/xdm/Xservers
 /etc/X11/xdm/Xsession
 /etc/X11/xdm/Xsetup_0
 /etc/X11/X
 /etc/X11/XF86Config

                  Figura 7.17: Buscando archivos por nombre.

BUSCANDO ARCHIVOS POR TAMAÑO

Otro uso comun del comando find es la busqueda de archivos por tamaño.
Para buscar archivos por tamaño, en vez de utilizar la opcion -name
utilizamos la opcion -size. A continuacion de esta opcion debemos
especificar el tamaño de los archivos a buscar y ademas si queremos
buscar archivos mas grandes o mas chicos que el tamaño especificado.
Veamos un ejemplo en la figura 7.18.

 # find /mp3 -size +700k
 /mp3/Nirvana/Lithium.mp3
 /mp3/Black Sabbath/paranoid/War Pigs.mp3
 /mp3/Led Zeppelin/Stairway to Heaven.mp3

          Figura 7.18: Buscando archivos por tamaño.

En este ejemplo, queremos encontrar todos los archivos que tengan un
tamaño mayor a 7000 Kbytes, a partir del directorio /mp3. Debemos
realizar dos observaciones:

 * El signo "+" que prefijamos al argumento que especifica el tamaño
   obliga al comando find a realizar un test. En este caso testeara que
   el tamaño del archivo sea mayor a 7000 Kbytes. En caso de querer
   buscar archivos de un tamaño menor al argumento debemos prefijar el
   simbolo "-". Si no usamos ningun simbolo, find buscara archivos cuyo
   tamaño sea exactamente igual al argumento especificado.

 * La letra "k" que agregamos luego del argumento informa a find que la
   unidad a utilizar sera Kbytes. Tambien podemos utilizar:

   - "c": Bytes

   - "w": Palabras (words) de 2 bytes cada una

   - "b": Bloques de 512 bytes cada uno (esta opcion es utilizada por
          defecto si no especificamos ninguna).

BUSCANDO ARCHIVOS POR FECHA DE MODIFICACION

Otra manera de utilizar el comando find para buscar archivos es
utilizando criterios de busqueda basados en fechas de modificacion de
los archivos. En este caso la opcion a utilizar es -mtime (modified
time). Vemos un ejemplo en la figura 7.19.

 # find /gome/tony/html -name *.htm -mtime -6
 /home/tony/html/commands.htm
 /home/tony/html/vi.htm

       Figura 7.19: Buscando archivos por fecha de modificacion.

El argumento de la opcion -mtime es un numero que especifica la
cantidad de dias. Si prefijamos un "-", entonces find buscara archivos
que hayan sido modificados dentro de la cantidad de dias especificada.
Si prefijamos un "+" al argumento, entonces se buscaran archivos que no
hayan sido modificados en ese periodo. Esto es particularmente util
cuando queremos generar listas de archivos viejos.

En este ejemplo, ilustramos como es posible combinar opciones para
formar criterios de busqueda mas avanzados. En este caso solo seran
devueltos como resultado los nombres de los archivos que terminen con
".htm" y hayan sido modificados en los ultimos 6 dias.

EFECTUANDO ACCIONES SOBRE LOS ARCHIVOS ENCONTRADOS

El comando find nos permite realizar ciertas acciones sobre los
archivos que se van encontrando como resultado de la busqueda. Esta es
una caracteristica muy util de este sistema.

Cuando un programa de Linux falla, el S.O. escribe, en el directorio de
trabajo que el programa tenia en el momento de la falla, un archivo
(usualmente muy grande) llamado core que se utiliza para realizar un
analisis de las causas por las que el programa fallo. En un sistema que
se utiliza para el desarrollo de programas estos archivos son muy
utiles, pero en la mayoria de los sistemas estos archivos no tienen
utilidad y pueden ser purgados periodicamente. En la figura 7.20
mostramos un comando find que buscara en todo el sistema de archivos a
los archivos que se llamen "core" y los eliminara.

  # find / -name core -exec rm {} \;
  rm: /proc/sys/net/core: is a directory
  find: /proc/410/fd: Permission denied
  find: /proc/411/fd: Permission denied
  find: /proc/433/fd: Permission denied
  rm: /usr/src/linux-2.2.5/net/core: is a directory

          Figura 7.20: Eliminando los archivos encontrados por find.

Vamos a analizar en detalle el comando utilizado:

 * La opcion -exec nos permite especificar un comando a realizar sobre
   cada archivo que find encuentra. El argumento de esta opcion es un
   comando. En este caso utilizamos el comando rm para que elimine los
   archivos encontrados.

 * Las llaves "{}" que agregamos a continuacion del comando rm seran
   reemplazadas por find con el nombre de cada archivo encontrado. Asi
   el comando rm tendra especificado como argumento el nombre de
   archivo correcto y podra eliminarlo.

 * La sintaxis del comando find nos obliga a colocar, luego del
   argumento a la opcion -exec, un punto y coma ";". Pero como la shell
   le otorga a este simbolo un significado especial (es el separador de
   comandos) debemos utilizar la barra "\" como caracter de escape para
   que la shell no interprete que queremos utilizarlo como separador de
   comandos. Veremos mas sobre esto en los capitulos siguientes.

OTROS USOS DEL COMANDO FIND

Es posible utilizar el comando find para realizar busquedas basadas en
muchos otros criterios, por ejemplo:

 * Buscar archivos vacios (-empty)
 * Buscar archivos pertenecientes a grupos de usuarios (-group)
 * Buscar archivos por nombre, pero que la evaluacion se realice sin
   diferenciar letras minusculas y mayusculas (-iname)
 * Buscar archivos por numero de links (-links)
 * Buscar archivos por tipos (directorios, links simbolicos, etc) (-type)
 * Buscar archivos por usuario (-user)

7.6 CAMBIANDO PERMISOS, GRUPOS Y DUEÑOS

La habilidad de poder especificar los permisos, grupos y dueños de los
archivos para cada archivo en particular es uno de los puntos mas
fuertes del S.O. Linux y de todos los demas UNIX.

Los comandos chmos (change mode), chown (change owner) y chgrp (change
group) se utilizan para cambiar los derechos de acceso de los archivos
y directorios.

Se debe tener en cuenta que para poder cambiar los derechos de acceso
de un archivo debemos ser dueño del mismo. Existe una excepcion a esta
regla que es el "superusuario" :).

EL SUPERUSUARIO PUEDE CAMBIAR LOS DERECHOS DE ACCESO DE CUALQUIER
ARCHIVO O DIRECTORIO.

Como vimos anteriormente, las tres operaciones que pueden ser
realizadas sobre un archivo son: lectura, escritura y ejecucion. Por
cada archivo existen tres niveles de privilegio:

 * user: es el dueño del archivo

 * group: es el grupo a el cual pertenece el archivo

 * others: es el universos (otros usuarios) de usuarios restantes

Por cada nivel de privilegio, es posible setear los permisos para las
tres operaciones de cada archivo o directorio. Mas especificamente por
cada nivel de privilegio, cada operacion puede estar permitida o
denegada.

7.6.1 AVERIGUANDO LOS DERECHOS DE ACCESO DE UN ARCHIVO

Para averiguar que permisos tiene un archivo, que usuario es dueño y a
que grupo pertenece, podemos utilizar el comando ls -l que nos muestra
un listado largo de los archivos. Por ejemplo:

 # ls -l
 total 15
 -rw-r--r--   1 tony   users       7559 May 12 04:31 commands.htm
 -rw-r--r--   1 tony   users       3817 May 12 04:31 krabber-2.html
 -rw-r--r--   1 tony   users       2880 May 12 04:31 vi.htm

Cada entrada del listado, en su comienzo, tiene una serie de simbolos
que especifican los permisos del archivo. La tercer columna de la
entrada muestra el usuario dueño del archivo y la columna siguiente
especifica el grupo al cual pertenece el archivo. En este caso el dueño
de los archivos es el usuario tony y los mismos pertenecen al grupo
users. La identificacion de los permisos es un poco mas complicada.

La informacion de los permisos de cada archivo se encuentra en el
primer campo de la entrada del listado. Este campo es una serie de
simbolos. El primer simbolo especifica el tipo de archivo (ver tabla
7.1). Los demas simbolos especifican los permisos seteados sobre el
archivo. El formato es el siguiente (ver figura 7.21):

 * Los tres primeros simbolos especifican los permisos de lectura,
   escritura y ejecucion para el usuario dueño del archivo.

 * Los siguientes tres simbolos especifican los permisos del archivo
   para los usuarios que pertenecen al grupo al cual el archivo
   pertenece.

 * Los ultimos tres simbolos muestran los permisos del universo
 restante.

          _________ Permisos del dueño
         |
         |      ___ Permisos del grupo
        _|_   _|_
        | |   | |
       -rwxrwxrwx
           | ||||_____ Permiso de ejecucion
           °|°||______ Permiso de escritura
            | |_______ Permiso de lectura
            |
            |_______Permisos del grupo

            Figura 7.21: Permisos de un archivo

Los tres simbolos de cada uno de los tres niveles de privilegio se
interpreta de la siguiente manera:

 1. "r" el archivo tiene permiso de lectura en este nivel de
 privilegio.

 2. "w" el archivo tiene permiso de escritura en este nivel de
 privilegio.

 3. "x" el archivo tiene permiso de ejecucion en este nivel de
 privilegio.

En cualquiera de los casos, un simbolo "-" significa que no se tiene el
permiso determinado. En el ejemplo anterior, los tres archivos tienen
permiso de lectura para todos los niveles de privilegio, pero solo el
dueño tiene permiso de escritura y ninguno de los niveles tiene permiso
de ejecucion, lo que quiere decir que nadie podra ejecuar ninguno de
los archivos. Esto tiene sentido ya que no son ejecutables, son
archivos "html" de hipertexto.

Es usual que los miembros del grupo tengan los mismos o menos
privilegios que el dueño del archivo y que los demas usuarios tengan
los mismos o menos privilegios que los de los miembros del grupo, pero
Linux no nos impone ninguna restriccion sobre el seteo de los permisos.
Facilmente podemos hacer que un archivo no pueda ser leido por su dueño
pero que los demas usuarios puedan hacerlo. (Aunque no tendria sentido
desde un punto de vista practico).

7.6.2 CAMBIANDO LOS PERMISOS

Existen dos formas de cambiar los permisos con el comando chmod. Una de
ellas es utilizando el modo simbolico y la trataremos a continuacion.
La otra forma es utilizando el modo numerico octal y usualmente es
!!ODIADA!! por los usuarios novatos. Esta forma sera tratada en segundo
termino.

MODOS DE ACCESO SIMBOLICOS

Una palabra de control de modos de acceso simbolica consiste en tres
partes: quienes, operador y permisos. "Quienes" especifica sobre que
niveles de privilegio setearemos los permisos. El "operador" es la
operacion a plicar: agregar, quitar o setear los permisos. Veamos un
ejemplo en la figura 7.22.

 # ls -l
 -rw-r--r--   1 tony    users     1090 May 29 17:04 file
 # chmod go-r file
 # ls -l
 -rw-------   1 tony    users     1090 May 29 17:04 file
 # chmod g=u file
 # ls -l
 -rw-rw----   1 tony    users     1090 May 29 17:04 file

       Figura 7.22: Cambiando permisos utilizando el modo simbolico.

En este ejemplo vemos que el archivo de nombre file tiene permiso de
lectura para todos los usuarios, pero su dueño es el unico que tiene
permiso de escritura. Luego ejecutamos.

 ==> chmod go-r file

En este comando el campo "quienes" esta formado por g (group) y o
(others), el operador es "-" por lo tanto se quitaran los permisos
especificados, que en este caso es unicamente el permiso de lectura "r"
(read). Luego de estos tres campos se debe especificar el/los archivos
sobr los que queremos modificar los permisos. Luego de cambiar los
permisos, verificamos que el archivo ya no tiene permiso de lectura ni
para los usuarios del grupo, ni para los demas. Luego ejecutamos:

 ==> chmod g=u file

Aqui el campo "quienes" contiene solo el grupo. El operador es este
caso es "=" por lo que los permisos del grupo seran seteados iguales a
los del usuario.

Los valores que pueden tomar cada campo de la palabra de control
simbolico se muestran en la tabla 7.2.

   Quienes Operador Permisos
 -------------------------------------------------------------------------
 u Usuarios - Eliminar el permiso
 r Lectura (read)
 g Grupo + Agregar el permiso
 w Escritura (write)
 o Otros = Setear el permiso
 x Ejecucion
 (execute)
 a Todos (all)
 u Permisos actuales del usuario
                                        g Permisos actuales del grupo
                                        o Permisos actuales del resto

                  Tabla 7.2. Formando la palabra de control chmod.

MODOS DE ACCESO EN NOTACION OCTAL

Muchas personas prefieren especificar los modos de acceso de los
archivos utilizando el modo simbolico. Pero el comando chmod tambien
nos permite utilizar una especificacion numerica. Aunque uno prefiera
utilizar la notacion simbolica es bueno entender la notacion numerica
octal de modos de acceso de los archivos en esta notacion. Mas aun si
vamos a dedicarnos a la administracion de un sistema, nos encontraremos
con la notacion octal muy frecuentemente. Como usuario, podemos
encontrar situaciones en las que los comandos mv, cp, ln, rm necesiten
confirmacion de las acciones a realizar y nos especifiquen el modo de
acceso del archivo en notacion octal.

Los numeros del sistema octal, se encuentran en base 8. Lo que
significa que los digitos octales son 0, 1, 2, 3, 4, 5, 6 y 7. Cada
digito octal es representado por tres digitos binarios (0 o 1), por
esto la notacion octal es practica para represntar cosas que se agrupan
en trios, ya que solo un digito octal puede representar todas las
posibilidades.

Un solo digito puede servirnos para representar un conjunto de permisos
de lectura/escritura/ejecucion como vemos en la tabla 7.3.

Como un digito octal puede guardar un conjunto de permisos, necesitamos
tres digitos para representar los modos de acceso de un archivo, un
digito para los permisos del usuario, otro para los permisos del grupo
y otro para los permisos de los demas usuarios.

Una diferencia grande con la utilizacion de la notacion simbolica es
que con el modo octal debemos especificar completamente el modo de
acceso del archivo y no podemos agregar o quitar permisos. Veamos
varios ejemplos en la fihura 7.23.

  Digito Octal   Permiso de lectura   Permiso de escritura   Permiso de ejecucion
       0                  no                  no                    no
       1                  no                  no                    si
       2                  no                  si                    no
       3                  no                  si                    si
       4                  si                  no                    no
       5                  si                  no                    si
       6                  si                  si                    no
       7                  si                  si                    si

           Tabla 7.3: Especificacion de modos de acceso con notacion octal.

  # chmod 666 file
  # ls -l file
  -rw-rw-rw-    1 tony    users       1090 May 29 17:04 file
  # chmod 000 file
  # ls -l file
  ----------    1 tony    users       1090 May 29 17:04 file
  # chmod 755 file
  # ls -l file
  -rwxr-xr-x    1 tony    users       1090 May 29 17:04 file
  # chmod 700 file
  # ls -l file
  -rwx------    1 tony    users       1090 May 29 17:04 file

             Figura 7.23: Seteando permisos utilizando la notacion octal.

7.6.3 CAMBIANDO EL DUEÑO Y EL GRUPO DE LOS ARCHIVOS

Los comandos chown (change owner) y chgrp (change group) cambian el
dueño y el grupo asociados con un archivo. Estos comandos son
usualmente utilizados cuando un usuario hereda archivos de otro usuario
o cuando obtiene copias de archivos de otros usuarios. El siguiente
comando cambiara el dueño de todos los archivos del directorio actual
al usuario juan:

 ==> chown juan *

El nombre del nuevo dueño debe ser un nombre de usuario valido o un
numero de identificacion de usuario (UID) valido. Los nombres de
usuarios y los respectivos UID's se encuentran en el archivo
/etc/passwd. En algunas versiones de UNIX/Linux el comando chown solo
esta permitido al superusuario. El siguiente comando asociara el grupo
users con el archivo example.tex.gz:

 ==> chgrp users example.tex.gz

Los grupos que se pueden utilizar con el comando chgrp pueden ser
nombres de grupos o numeros de identificacion de grupos (GID) que se
encuentran en el archivo /etc/group.


PARTE II


 Contenido

  Introduccion (lo esta leyendo)

  8. Utilidades Adicionales
     8.1  Utilidades de monitoreo
          8.1.1  date: Muestra la fecha y hora actuales
          8.1.2  who: Lista los usuarios logueados actualmente
          8.1.3  ps: Listado de los procesos
          8.1.4  free: Sumario de la utilizacion de la memoria
          8.1.5  top: Actividad del procesador
          8.1.6  df: Muestra el espacio libre en los sistemas de archivos
          8.1.7  du: Uso del disco
     8.2  Utilidades para trabajar con texto
          8.2.1  cat: Mostrar archivos
          8.2.2  head: Muestra el comienzo de un archivo
          8.2.3  tail: Muestra el final de un archivo
          8.2.4  ascii-xfr: Convierte archivos de texto
          8.2.5  more: Filtro para visualizacion de texto por pantalla
     8.3  Utilidades para agrupar y comprimir archivos
          8.3.1  gzip y bzip2: Compresion de archivos
          8.3.2  tar: Agrupa archivos
     8.4  Utilidades de ayuda
          8.4.1  man: Informacion de los comandos y utilidades
     8.5  Otras utilidades
          8.5.1  passwd: Cambiando el password
  9. Instalacion de software adicional
     9.1  Software distribuido con codigo fuente
          9.1.1  La distribucion
          9.1.2  La configuracion
          9.1.3  La compilacion
          9.1.4  El directorio /usr/local
          9.1.5  La instalacion
     9.2  El sistema de paquetes RPM
          9.2.1  Convenciones en los nombres de los paquetes
          9.2.2  La base de datos RPM
          9.2.3  Modos de operacion de rpm
     9.3  Utilizacion de librerias
          9.3.1  Directorios de las librerias
          9.3.2  Instalacion de librerias.
  10. Montando sistemas de archivos
    10.1  Sistemas de archivos y particiones
    10.2  Sintaxis del comando mount
    10.3  Montando sistemas de archivos
          10.3.1  Tipos de sistemas de archivos
    10.4  Desmontando sistemas de archivos
    10.5  El archivo /etc/fstab
          10.5.1  Campos de cada entrada
          10.5.2  Uso del archivo fstab
          10.5.3  Permitiendo montar sistemas de archivos a usuarios normales
  11. El kernel y los modulos
    11.1  ¿Que es el kernel?
    11.2  La interaccion
          11.2.1  Las librerias del sistema
          11.2.2  Las utilidades del sistema
    11.3  ¿Que son los modulos?
    11.4  Personalizando el kernel
          11.4.1  Eligiendo la configuracion adecuada
          11.4.2  Compilando el kernel
          11.4.3  Compilando los modulos
          11.4.4  Instalando los modulos
          11.4.5  Instalando el nuevo kernel
          11.4.6  Cargando y decargando los modulos
          11.4.7  Las dependencias entre los modulos
          11.4.8  Una carga de modulos mas inteligente
    11.5  Actualizando nuestro kernel
          11.5.1  Obteniendo el kernel
          11.5.2  Instalando las fuentes del kernel
  12. Aspectos avanzados de la shell
    12.1  Programas de la shell (scripts)
    12.2  Variables de la shell
          12.2.1  Exportando variables de la shell
          12.2.2  Variables automaticas de la shell
          12.2.3  Variables estandar de la shell
    12.3  El camino de busqueda (path)
    12.4  Caracteres especiales - "Quoting"
    12.5  Estado de salida de los comandos
    12.6  Los argumentos
    12.7  Estructuras de control
          12.7.1  Condicionales simples
          12.7.2  El condicional if
          12.7.3  Los loops condicionales while y until
          12.7.4  La sentencia for
          12.7.5  La sentencia case
    12.8  Evaluacion de condiciones - Test
    12.9  Evaluacion de expresiones - Expr


CAPITULO 8

UTILIDADES ADICIONALES

8.1 UTILIDADES DE MONITOREO

El S.O. Linux nos provee de un conjunto de utilidades que nos permiten
monitorear nuestro sistema, desde enterarnos de la fecha actual hasta un
sumario del uso de la memoria.

8.1.1 date: MUESTRA LA FECHA Y LA HORA ACTUAL

# date
Sat May 29 23:54:23 ART 1999

El comando date tambien se utiliza para setear la fecha y la hora del
sistema, pero esto solo puede hacerlo el superusuario.

8.1.2 who: LISTA LOS USUARIOS LOGUEADOS ACTUALMENTE

El comando who muestra una lista de las personas que estan usando
actualmente el sistema.

# who
tony     tty1   May 29 23:23
root     tty2   May 29 20:15

8.1.3 ps: LISTADO DE PROCESOS

El comando ps muestra una lista de los procesos que se encuentran
corriendo en el sistema. Usualmente este comando es utilizado por los
programadores y los administradores del sistema para ver que es lo que
esta sucediendo en el sistema. Los usuarios utilizan ps para averiguar
el PID (process identification number) de los procesos errantes para
poder matarlos.

Si ejecutamos ps, veremos una lista formada por los procesos que
nosotros estamos ejecutando, pero no veremos los procesos de otros
usuarios. Vemos un ejemplo en la figura 8.1.

En el listado que aparece como salida del comando ps vemos el PID, la
terminal que lo controla, el estado del proceso, el tiempo de ejecucion
y el comando que invoco al proceso. Los PIDs se asignan secuencialmente
a medida que cada proceso comienza y ciclan otra vez hacia 1 cuando
alcanzan 32767. Si un proceso se esta ejecutando en "background",
podemos monitorearlo con el comando ps.

 # ps
   PID TTY STAT  TIME COMMAND
   491   1 S    0:00 /bin/login -- tony
   492   1 S    0:00 -bash
   503   1 S    0:00 sh /usr/X11R6/bin/startx
   504   1 S    0:00 xinit /home/tony/.xinitrx --
   508   1 S    0:02 wmaker
   509   1 S    0:06 kfm
   512   1 S    0:00 mount.app
   513   1 S    0:00 asclock -shape
   514   1 S    0:00 wmmixer -w
   515   1 S    0:00 wmmom
   516   1 S    0:00 wmmom -s
   521   1 S    0:23 emacs -fn 9x15
   525  p5 S    0:00 /bin/bash
   572  p6 R    0:00 ps

              Figura 8.1: Listando los procesos.

Si ejecutamos ps aux veremos todos los procesos que se estan ejecutando
en el sistema. Cada proceso tendra especificado el usuario dueño del
mismo.

8.1.4 free: SUMARIO DE LA UTILIZACION DE LA MEMORIA

El comando free muestra la cantidad de memoria fisica utilizada y
libre, la utilizacion del espacio "swap", la cantidad de memoria
compartida y la utilizacion de los "buffers". La opcion -b muestra la
cantidades en bytes, la opcion -k en kilobytes (es la predeterminada) y
la opcion -m en megabytes. Vemos la salida de este comando en la figura
8.2.

 # free
            total       used       free     shared    buffers    cached
 Mem:       95696      70068      25628      39672       6840     28760
 -/+ buffers/cache:    34468      61228
 Swap:      40156          0      40156

              Figura 8.2: Visualizando la informacion de la memoria
                          utilizada en el sistema.

8.1.5 top: ACTIVIDAD DEL PROCESADOR

El comando top provee una vision en tiempo real de la actividad del
procesador. Nos muestra una lista de los procesos que utilizan el CPU
de manera intensiva y provee una interfase interactiva para la
manipulacion de los procesos. El comando top puede mostrar el listado
de los procesos ordenados por el uso de CPU, utilizacion de memoria o
tiempo de ejecucion.

8.1.6 df: MUESTRA EL ESPACIO LIBRE EN LOS SISTEMAS DE ARCHIVOS

El comando df (disk free) muestra el espacio disponible en cada sistema
de archivos actualmente montado. La unidad utilizada es un bloque de
1K, pero podemos modificar esto invocando a df con la opcion -h (human)
para que muestre la informacion del espacio disponible en un formato
mas accesible. Vemos un ejemplo en la figura 8.3.

 # df
 Filesystem         1024-blocks  Used Available Capacity Mounted on
 /dev/hda3            1701926 1306039   307932     81%   /
 /dev/hda2             305064  200456   104608     66%   /mnt/win95
 /dev/hda1            2096450 1510124   586326     72%   /mnt/nt
 /dev/hdc1            2108544 1620352   488192     77%   /mnt/akenaton
 # df -h
 Filesystem            Size  Used  Avail  Capacity Mounted on
 /dev/hda3             1.6G  1.2G   301M     81%   /
 /dev/hda2             298M  196M   102M     66%   /mnt/win95
 /dev/hda1             2.0G  1.4G   573M     72%   /mnt/nt
 /dev/hdc1             2.0G  1.5G   477M     77%   /mnt/akenaton

           Figura 8.3: Visualizando el espacio disponible en los
                       sistemas de archivos.

8.1.7 du: USO DEL DISCO

El comando du (disk usage) nos sirve para averiguar cuanto espacio
estan ocupando nuestros archivos. Cuando es invocado sin argumentos, du
nos devuelve una lista con los subdirectorios del directorio actual y
el espacio ocupado por cada uno de ellos. Vemos un ejemplo en la figura
8.4a.

 # pwd
 /home/tony/docs/linux
 # du
 1446 ./images
 137 ./xtras
 2114 .

        a. Visualizando el espacio ocupado por cada subdirectorio.

Es usual querer saber cuanto espacio esta ocupando un directorio junto
con todos sus subdirectorios. Para ello podemos utilizar el comando du
con la opcion -s y como argumento el directorio en cuestion. Esta
opcion realiza un sumario de espacio ocupado por cada argumento pasado
al comando. Si no pusieramos la opcion -s el comando nos daria como
salida un listado de los subdirectorios que se encuentran en ese
directorio y el espacio que ocupan los mismos. Vemos un ejemplo de esto
en las figuras 8.4b y c.

 # du -s Desktop
 14 Desktop

        b. Visualizando el espacio ocupado por un subdirectorio

 # du Desktop
 2 Desktop/Trash
 8 Desktop/Templates
 2 Desktop/Autostart
 14 Desktop

        c. Visualizando el espacio ocupado por los subdirectorios de un
           directorio.

         Figura 8.4: Visualizando el espacio ocupado por los archivos.

8.2 UTILIDADES PARA TRABAJAR CON TEXTO

8.2.1 cat: MOSTRAR ARCHIVOS

El uso estandar de este comando es el de mostrar archivos en nuestra
terminal. Ademas el comando cat se puede utilizar para concatenar
archivos. Ejemplos en las figuras 8.5a y b.

 # cat /etc/printcap
 ##PRINTTOOL3## LOCAL cdj550 300x300 a4 {} DeskJet550 Default 1 1
 hp|lp:\
 :sd=/var/spool/lpd/hp:\
 :mx#0:\
 :sh:\
 :lp=/dev/lp0:\
 :if=8/var/spool/lpd/filter:

          a. Utilizando cat para ver el contenido de un archivo.

 # cat mess[123] > message
 # cat message
 Contenido del mensaje 1
 .....
 Contenido del mensaje 2
 .....
 Contenido del mensaje 3
 .....

          b. Utilizando cat para concatenar archivos.

Otro uso muy comun de cat es en la creacion de archivos de texto con
muy pocas lineas. A veces necesitamos crear archivos con muy pocas
lineas de textos y no se justifica cargar un editor de texto para
hacerlo. Si ejecutamos cat sin argumentos, el comando leera caracteres
de la entrada estandar hasta encontrar un caracter de fin de archivo
(Ctrl+D). Ejemplo en la figura 8.5c.

 # cat > /etc/motd
 Se recuerda a todos los usuarios que el espacio de disco que tiene
 asignado es como maximo 4MB.
 ^D

          c. Utilizando cat para crear archivos.

8.2.2 head: MUESTRA EL COMIENZO DE UN ARCHIVO

Hay ocasiones en las que queremos saber cual es el contenido de un
archivo, pero no queremos visualizarlo todo, ya sea por que es muy
grande y porque tardariamos mucho tiempo o porque se visualiza tan
rapido que lo unico que vemos es una serie de flashs de caracteres en
la pantalla. El comando head nos permite visualizar las primeras lienas
de un archivo (10 por defecto). Usando la opcion -n <N> podemos
visualizar las primeras N lineas del archivo. Vemos un ejemplo en la
figura 8.6.

 # head -n 5 .x11amp/config
 [x11amp]
 allow_multiple_instances=FALSE
 always_show_cb=TRUE
 convert_underscore=TRUE
 conert_%20=TRUE

               Figura 8.6: Mostrando el comienzo de un archivo.

8.2.3 tail: MUESTRA EL FINAL DE UN ARCHIVO

El comando tail funciona de la misma forma que head, con la diferencia
de que muestra las ultimas lienas de un archivo en vez de las primeras.
Tambien visualiza 10 lineas por defecto, y soporta la opcion -n <N>
para visualizar las N ultimas lineas del archivo. Veamos un ejemplo en
la figura 8.7.

 # tail -n 5 /var/log/dmesg
  hdc: [PTBL] [523/128/63] hdc1
  NTFS version 990102
  VFS: Mounted root (ext2 filesystem) readonly.
  Freeing unused kernel memory: 48k freed
  Adding Swap: 40156k swap-space (priority -1)

               Figura 8.7: Mostrando en final de un archivo.

8.2.4 ascii-xfr: CONVIERTE ARCHIVOS DE TEXTO.

Linux se diferencia de otros S.O. en el tratamiento de los archivos de
texto, mas especificamente en el formato del fin de linea. MS-DOS,
Windows 95/98 y NT identifican el fin de linea con 2 caracteres: LF
(Line Feed) y CR (Carriage Return), avance de linea y retorno de carro
respectivamente. Linux, en cambio identifica el fin de linea con un
solo caracter LF (Line Feed).

Por esto, un problema tipico es el de la transferencia de archivos de
un sistema Linux hacia otro que entiende el fin de linea con 2
caracteres. Por ejemplo, si llevamos un archivo de texto de un sistema
Linux a un sistema Windows y visualizamos su contenido, veremos que se
encuentra todo el texto sobre una unica linea. Esto es porque no habia
carateres de retorno de carro en el archivo y por lo tanto Windows no
encontro ningun final de linea. Si en cambio, traemos un archivo de
texto de Windows hacia Linux, tendremos un caracter de retorno de carro
de mas por cada linea.

La solucion a esto claramente no puede ser la edicion manual del
archivo en cuestion, cosa que se puede volver inmediatamente tediosa y
tiene asociada una alta probabilidad de error. La utilidad ascii-xfr es
un filtro de archivos de texto que se ocupa de realizar estas
traducciones de formatos de archivos de texto ASCII. Esta utilidad
tiene dos modos de operacion:

 * Envio: En este modo se transmite el caracter de fin de linea como
          CR-LF. Se invoca con la opcion -s (Send).

 * Recepcion: Se elimina de cada fin de linea el caracter de CR. Se
              invoca con la opcion -r (Receive).

Esta utilidad es invocada comunmente como un filtro, ya que lee de la
entrada estandar (al recibir) y escribe en la salida estandar (al
enviar), pero puede ser utilizada conjuntamente con redireccion de la
entrada o la salida para lograr otros resultados.

El siguiente comando crea una copia de un archivo del archivo de texto
ascii-linux.txt en formato de Linux a ascii-win.txt en formato de texto
de Windows; una vez ejecutado este comando, se creara el archivo
ascii-win.txt y podra ser utilizado como un archivo de texto normal
sobre Windows.

 ==> ascii-xfr -s ascii-linux.txt > ascii-win.txt

El siguiente comando nos sirve para crear una copia en formato de texto
Linux de un archivo de texto creado en Windows.

 ==> cat ascii-win.txt | ascii-xfr -r ascii-linux.txt

8.2.5 more: FILTRO PARA VISUALIZACION DE TEXTO POR PANTALLA

El comando more es un filtro para ver un texto pagina por pagina. Es
utilizado normalmente para visualizar los contenidos de un archivo muy
grande. Tambien se utiliza en conjuncion con otros comandos para poder
ver la salida de los mismos pagina por pagina. Ejemplos:

 ==> more /var/log/dmseg

Este comando nos muestra el contenido del archivo de "log" que se escribe
al iniciarce el sistema y contiene los mensajes que el kernel emite al
iniciarse.

 ==> ls -l | more

Este es un comando tipico de los usuarios de Linux. Sirve para listar
los contenidos de un directorio en formato largo, y poder ver el
listado pagina por pagina. En este caso more se detendra cuando una
pantalla se llene y esperara que apretemos "SPACE" para pasar a la
siguiente pagina. Si apretamos "b" (back), volvemos a la pagina
anterior y si orpimimos "q" (quit) interrupiremos inmediatamente la
visualizacion.

8.3 UTILIDADES PARA AGRUPAR Y COMPRIMIR ARCHIVOS

8.3.1 gzip y bzip2: COMPRESION DE ARCHIVOS

Hay dos utilidades de compresion sin perdida que comunmente son
provistas con las distribuciones de Linux: gzip y bzip2. El primero
utiliza el algoritmo de compresion "Lempel-Ziv" mientras que el segundo
utiliza una tecnica llamada "ordenamiento de bloques". Existen otras
utilidades de compresion como lo son pack y compress, pero hoy en dia
son consideradas obsoletas y las dos primeras son las que mas se
utilizan.

El modo de uso es en ambas utilidades igual, por lo que ilustraremos
con ejemplos indistintamente. Tambien haremos unas pruebas para mostra
cual de las dos utilidades es mas eficiente.

Estas utilidades reciben una lista de argumentos (que deben ser
archivos) y comprimen cada uno de ellos sobreescribiendo los archivos
originales y agregando como sufijo al nombre del archivo la extension
gz. Veamos un ejemplo en la figura 8.8a.

 # ls -l
 -rw-r--r--   1 tony   users       7559 May 12 04:31 commands.htm
 -rw-r--r--   1 tony   users       3817 May 12 04:31 krabber-2.html
 -rw-r--r--   1 tony   users       2880 May 12 04:31 vi.htm
 # gzip commands.htm krabber-2.html vi htm
 # ls -l
 -rw-r--r--   1 tony   users       2050 May 12 04:31 commands.htm.gz
 -rw-r--r--   1 tony   users       1746 May 12 04:31 krabber-2.html.gz
 -rw-r--r--   1 tony   users       1102 May 12 04:31 vi.htm.gz
 # gzip -d *.gz
 # ls -l
 -rw-r--r--   1 tony   users       7559 May 12 04:31 commands.htm
 -rw-r--r--   1 tony   users       3817 May 12 04:31 krabber-2.html
 -rw-r--r--   1 tony   users       2880 May 12 04:31 vi.htm

           a. Utilizando gzip para comprimir varios archivos

 # ls -l netscape
 -r-xr-xr-x   1 root   root      12078064 Oct 13  1998 netscape
 # gzip netscape
 # ls -l netscape.gz
 -r-xr-xr-x   1 root   root       5138529 Oct 13  1998 netscape.gz
 # gzip -d netscape.gz
 # bzip2 netscape
 # ls -l netscape.bz2
 -r-xr-xr-x   1 root   root       4739906 Oct 13  1998 netscape.bz2
 # bzip2 -d netscape.bz2
 # ls -l netscape
 -r-xr-xr-x   1 root   root      12078064 Oct 13  1998 netscape

           b. Testeando al eficiencia de ambas utilidades.

        Figura 8.8: Utilizando gzip y bzip2 para comprimir archivos.

Como vemos en el ejemplo, tanto gzip como bzip2 son invocados con la
opcion -d (decompress) para descomprimir un archivo comprimido. Asi el
archivo recupera su tamaño y nombre original.

En la figura 8.8b vemos una comparacion entre ambas utilidades de
compresion. Se tomo el archivo ejecutable del Netscape Communicator 4.5
como objeto de prueba. El archivo, sin comprimir, ocupa exactamente
12078064 bytes. Al comprimir con gzip obtuvimos un archivo con un
tamaño de 5138529 bytes, lo que implica un grado de compresion del 57.4
%. Al comprimirlo con bzip2 obtuvimos un archivo de 4739906 bytes lo
que implica un grado de compresion del 60.76%. En este caso comprimio
mejor bzip2. En general bzip2 realiza mejores compresiones que gzip
pero con el costo de tardar un poco mas. Hoy, esta ganando terreno la
utilizacion del bzip2.

En el ejemplo anterior, vimos los grados de compresion que alcanzaron
ambas utilizadades. Estos grados son muy buenos teniendo en cuenta que
el archivo objeto de la prueba era un archivo binario. En general, se
logran mejores compresiones sobre los archivos de texto, por ejemplo:
fuentes de algun programa. Luego en la seccion que trata sobre la
utilidad tar veremos un ejemplo de esto, comprimiendo las fuentes del
kernel de Linux.

8.3.2 tar: AGRUPAR ARCHIVOS

Las utildades gzip y bzip2 son muy buenas comprimiendo grandes
archivos, pero no pueden hacer mucho sobre archivos pequeños. Primero,
los archivos pequeños son pequeños, valga la redundancia, y
comprimirlos no nos trae mucho beneficio. Pero el problema, es que
existe una dificultad tecnica que tenemos que entender. En Linux, el
espacio en disco es reservado de a bloques de 1 Kilobyte, en los
sistemas de archivos de otros Unix se reserva espacio en "clusteres" de
2, 4 o hasta 8 bloques de 512 bytes. Esto significa que si creamos un
archivo que solo contiene un caracter, en Linux ocupara 1 Kilobyte y en
otros Unix puede ocupar de 1 a 4 Kilobytes.

La implicancia directa de esto es que no nos trae ningun beneficio
comprimir un archivo de, por ejemplo 512 bytes ya que por mas que
comprimido ocupe menos espacio, seguira almacenado en un bloque de 1
kilobyte.

Otra dificultad con los archivos pequeños, es que, em general, se tiene
muchisimos de ellos. Si tenemos unos pocos archivos de 1K no tendremos
problemas, pero tener 5.000 o 10.000 archivos de ese tamaño pueden
hacernos perder espacio rapidamente.

La utilidad tar soluciona esto y otros problemas. Esta utilidad fue
originalmente desarrollada como un programa para escribir archivos de
cintas magneticas, su nombre es "Tape archiver". Las cintas se tratan
como un gran archivo secuencial y tar fue diseñado para empaquetar
conjuntos de archivos en un gran archivo para ser almacenado en cinta.
Todavia se continua utilizando tar para realizar backups en cinta
magnetica, pero tambien es muy util para archivar grandes conjuntos de
archivos en un unico archivo llamado "tar-archive".

Tar puede ahorrar espacio ya que almacena archivos en un gran archivo
sin la limitacion de un tamaño de cluster fijo. Los archivos se colocan
uno despues del otro separados por un encabezado. Un grupo de archivos
pequeños dentro de un tar-archive puede ser facilmente comprimido
utilizando las utilidades gzip o bzip2.

Los compresores se utilizan como complemento de la utilidad tar para
comprimir un arbol de directorios recursivamente. Primero se agrupan
todos los archivos y directorios a comprimir en un tar-archive y luego
este es comprimido con la ayuda de un compresor, ya sea gzip o bzip2.
En la figura 8.9a vemos como se utiliza tar en conjunto con un
compresor para crear un archivo comprimido que contenga toda la
informacion del subdirectorio en cuestion, en este caso las fuentes del
kernel de Linux, version 2.2.5. Elegimos las fuentes del kernel como
archivo objeto porque son muchismos archivos de texto y con una
estructura de directorios y subdirectorios muy compleja. Asi vemos que
con un par de comandos almacenamos toda la estructura de subdirectorios
en un unico archivo y luego lo comprimimos para que ocupe poco espacio.

 # du -hs linux-2.2.5
 51M linux-2.2.5
 # tar -c linux-2.2.5 | gzip > linux-2.2.5.tar.gz
 # du -hs linux-2.2.5.tar.gz
 13M linux-2.2.5.tar.gz

    a. Comprimiendo un arbol de directorios.

 # gzip -dc linux-2.2.5.tar.gz | tar -xf -
 # du -hs linux-2.2.5
 51M linux-2.2.5

    b. Descomprimiendo un arbol de directorios.

  Figura 8.9: Comrpimiendo y descomprimiendo un arbol de directorios.

El comando utilizado es tar -c ya que la opcion -c (create) hace que el
comando tar cree un nuevo tar-archive y como no se especifica un
archivo de salida (opcion -f nombre) tar envia la salida a la salida
estandar. La cañeria creada permite que el comando gzip obtenga la
salida de tar y comprima enviando el resultado a la salida estandar la
cual es redireccionada al archivo linux-2.2.5.tar.gz. Tambien vemos que
el directorio, junto con todos sus subdirectorios y archivos ocupa 51
Megabytes. Una vez agrupado y comprimido el tamaño del archivo es de
solo 13 Megabytes, lo que implica un grado de compresion del 74.5%.

En la figura 8.9b mostramos como se puede descomprimir el archivo
linux-2.2.5.tar.gz.

El comando es otra vez una cañeria, pero esta vez en sentido inverso.
Se utiliza el comando gzip con la opcion -d para que descomprima y la
opcion -c para que envie el resultado a la salida estandar. Luego
utilizamos el comando tar para desagrupar los archivos y necesitamos
agregrales las opciones -x (extract) para que extraiga los archivos y
-f para indicarle que es un tar-archive. Ademas debemos agregarle el
simbolo "-" para indicarle que lea de la entrada estandar y asi pueda
recibir la salida del compresor. Luego realizamos un chequeo y vemos
que se encuentra el directorio linux-2.2.5 y que su tamaño es
nuevamente 51 Megabytes.

8.4 UTILIDADES DE AYUDA

8.4.1 man: INFORMACION DE LOS COMANDOS Y UTILIDADES

Los sistemas de la familia Unix, tiene un sistema de ayuda "on-line"
para los comandos y utilidades del sistema muy completo y practico que
es llamado "Man-Pages" (manuales).

La utilidad man es un programa que formatea (de darle forma) y visuliza
los manuales de los comandos y utilidades del sistema.

Esta utilidad se invoca con un argumento que debe ser un comando o
utilidad valida del sistema o cualquier programa que hayamos instalado
que posea manuales instalados. El siguiente comando nos mostrara el
manual del comando ls.

 ==> man ls

Dentro del entorno de la utilidad man hay varios comandos que es util
conocer:

 1- Avanzar: Avanzamos por las paginas del manual utilizando la barra
             espaciadora o "space".

 2- Retrocerder: Retrocedemos una pagina del manual utilizando la tecla
                 "b" (back).

 3- Salir: Salimos del manual con la tecla "q" (quit).

8.5 OTRAS UTILIDADES

8.5.1 passwd: CAMBIANDO EL PASSWORD

El comando passwd se utiliza para cambiar el "password" del usuario.
Algunas personas cambian su password periodicamente para mantener la
seguridad. El comando passwd primero nos obliga a ingresar el password
actual y si es valido nos pregunta dos veces el nuevo password, para
verificar que no nos hayamos equivocado. Ninguno de los passwords es
mostrado en la pantalla por cuestiones de privacidad y seguridad.

El superusuario (root) puede setear el password de cualquier usuario,
pero los usuarios ordinarios solo pueden cambiar sus propios passwords.

En algunos sistemas los passwords se "vencen", es decir que duran un
cierto tiempo. El sistema nos obligara a cambiar nuestro password la
proxima vez que iniciemos una sesion pasado el periodo de vencimiento.


CAPITULO 9

INSTALACION DE SOFTWARE ADICIONAL

Una vez instalado el sistema Linux, estamos en condiciones de utilizar
una gran cantidad de utilidades y programas que vienen como parte del
mismo. La gran mayoria del software que viene con las distribuciones de
Linux, es actualizado permanentemente, ya sea porque se perfecciona o
porque se le agregan nuevas caracteristicas. Ademas, hoy en Internet,
podemos conseguir una infinidad de programas adicionales de distintas
areas. Para poder instalar con exito cada uno de los programas que
conseguimos es necesario que conozcamos algunos detalles importantes.

Existen una gran cantidad de sitios en Internet, donde es posible
conseguir las ultimas versiones de los programas y utilidades mas
conocidas en el sistema Linux. En el apendice A se listan las
direcciones de los sitios mas importantes, los que no tenemos que dejar
de visitar.

9.1 SOFTWARE DISTRIBUIDO CON CODIGO FUENTE

El software para Linux o Unix, en general es distribuido con el codigo
fuente, ya que existen una gran cantidad de plataformas Unix con
distintas caracteristicas. Seria inviable que el autor del software
compile y genere una version ejecutable binaria del programa para cada
plataforma y la publique para que podamos disponer de ella. Para evitar
esto, cada version de la familia Unix posee un sistema de compilacion y
generacion de ejecutables como parte del sistema. Asi teniendo el
codigo fuente del programa, podemos compilar y generar una version
ejecutable del mismo, sobre nuestra plataforma y con todas las
caracteristicas de nuestro sistema, de forma casi transparente. La
obvia desventaja de esta aproximacion es el tiempo extra que tenemos
que invertir compilando los programas, sobre todo si los mismos son muy
grandes.

El echo de contar con el codigo fuente de los programas (usualmente C,
C++), nos da la posibilidad de poder modificar los mismos y adaptarlos
a nuestras necesidades particulares. Asi podemos modificar el codigo
fuente y volver a compilar el ejecutable, tantas veces como queramos.

Una complicacion adicional surge al encontrarse con el codigo fuente de
los programas: los mismos pueden necesitar utilizar librerias para
poder compilarlos. La seccion 9.3 se ocupa de explicar como podemos
instalar nuevas librerias en nuestro sistema.

9.1.1 LA DISTRIBUCION

La mayoria del software que podemos conseguir en Internet se encuentra
agrupado y comprimido con los formatos tar y gzip o bzip2
respectivamente.

Antes de realizar la instalacion es necesario descomprimir y desagrupar
los contenidos. Vamos a ver un ejemplo con el programa cdda2wav que es
una utilidad para copiar cd's de audio a formato de archivo de sonido
de onda (wav). El archivo de la distribucion es cdda2wav-1.0c.tar.gz.
El comando para descomprimir y desagrupar el contenido del archivo
puede ser:

 ==> tar -zxvf cdda2wav-1.0c.tar.gz

  o el equivalente

 ==> gzip -dc cdda2wav-1.0c.tar.gz | tar -xvf -

   NOTA: Si el formato es .tar.bz2 no es posible utilizar la primera
         forma del comando. Es necesario invocar un comando de la forma
         del segundo, reemplazando el descompresor gzip por el bzip2.

Luego de haber descomprimido y desagrupado las fuentes, en general,
obtendremos un directorio con los contenidos del archivo. En la figura
9.1 vemos el contenido del directorio obtenido.

 # cd cdda2wav-1.0c
 # ls
 Fronted               byteorder.h         md5c.h             scsilib
 GLP                   cdda2mp3            md5c.c             semshm.c
 HOWTOUSE              cdda2mp3.new        missing            semshm.h
 HPUX-Notes            cdd2wav.1           mkinstalldrs       setuid.c
 Makefile.am           cdd2wav.c           mycdrom.h          setuid.h
 Makefile.in           cdd2wav.h           mytype.h           sndconfig.c
 NEWS                  cdda_links          pitchplay          sndconfig.h
 OtherProgs            config.guess        raw.c              sun.c
 README                config.h            raw.h              sun.h
 README.2_0_33         config.sub          readmult           toc.c
 README.GoldstarR580B  configure           resample.c         toc.h
 README.INSTALL        configure.in        resample.h         tracknames.pl
 README.paranoia       global.h            ringbuff.c         tracknames.txt
 THANKS                install-sh          ringbuff.h         wav.c
 TODO                  interface.c         scan_scsi.linux    wav.h
 aclocal.m4            interface.h         scsi_cmds.c
 add_wav               lowlevel.h          scsi_cmds.h

    Figura 9.1: El contenido tipico de una distribucion de codigo fuente.

Es usual que los desarrolladores del software agregen en la
distribucion archivos INSTALL o README que son muy utiles al momento de
compilar e instalar, ya que especifican las instrucciones de
compilacion e instalacion que debemos seguir para poder instalar el
programa con exito.

A continuacion, vamos a explicar el proceso de compilacion e
instalacion mas comunmente utilizados. ES NECESARIO ACLARAR QUE NO TODO
EL SOFTWARE QUE PODEMOS CONSEGUIR SIGUE ESTAS CARCTERISTICAS. SIEMPRE
DEBEMOS REMITIRNOS, COMO PRIMER MEDIDA, A LAS INSTRUCCIONES RESPECTIVAS
DE CADA PROGRAMA.

9.1.2 LA CONFIGURACION

Como paso previo a la compilacion, debemos iniciar un proceso de
configuracion del software. El mismo escaneara nuestro sistema en busca
de los requerimientos del programa para ver si los mismos se encuentran
instalados o no, y para determinar otros parametros necesarios a la
hora de compilar.

Para iniciar este proceso de configuracion, debemos ejecutar el
comando:

 ==> ./configure

Dentro del directorio del programa. Seguiran una serie de mensajes de
estado y configuracion, los cuales terminaran en la generacion de los
archivos Makefile que son requisitos imprescindibles a la hora de
compilar. La salida de esta etapa son estos archivos que contienen las
instrucciones para que el compilador pueda trabajar.

  NOTA: Si en esta etapa el proceso de configuracion se detiene con un
        mensaje de error, es posible que nos este faltando una libreria
        o algo necesario para la configuracion del programa. Anotar
        precisamente el error y luego referirse a los archivos INSTALL
        o README respectivos a cada programa con el fin de determinar
        la causa del error.

9.1.3 LA COMPILACION

La compilacion es el proceso por el cual el texto fuente de un programa
es traducido al formato binario (leguaje entendido por la maquina) para
que la misma este en condiciones de ejecutarlo. Es una tarea automatica
(por lo menos desde el punto de vista del usuario). En general,
ejecutando el comando

  ==> make

(construir) daremos comienzo a la tarea de compilar el programa. Este
comando indica al compilador que comience su tarea, y el mismo, en base
a las instrucciones de los archivos Makefile generados en la etapa
anterior, ira construyendo los distintos componentes del programa, para
finalizar su tarea, vinculando los componentes generados en uno o mas
ejecutables que forman parte del programa. Estos ejecutables seran
guardados en el directorio donde tenemos el codigo fuente del programa.
Como paso restante, queda instalar los ejecutables y documentacion
(usualmente provista con el codigo fuente - no es necesario compilar)
en el directorio correspondiente, para asi poder comenzar a utilizar el
programa en nuestro sistema.

9.1.4 EL DIRECTORIO /usr/local

El directorio /usr/local usualmente es el lugar en la jerarquia de
archivos donde se instala el software adicional, es decir aquel
software que no haya sido provisto inicialmente con la distribucion del
S.O. Linux instalada.

La mayoria del software posee como destino de instalacion
predeterminado este directorio, por lo que el programa se instalara en
ese lugar. Este directorio posee una serie de subdirectorios que lo
forman, los mismos son (lista no exhaustiva):

 * /usr/local/bin: Es el directorio donde se guardan los ejecutables.

 * /usr/local/lib: Es el directorio donde se instalan las librerias.

 * /usr/local/man: Es el directorio donde los programas instalan sus
                   man-pages.

 * /usr/local/doc: Es el directorio donde se almacena la documentacion
                   adicional. Usualmente paginas Html.

 * /usr/local/include: Es el directorio donde se guardan los encabezados
                       de las librerias. Este directorio es escaneado por
                       los programas de configuracion, para ver si se
                       ecuentran disponibles ciertas librerias.

 * /usr/local/games: En este directorio se instalan los programas de
                     entretenimiento.

 * /usr/local/share: Este directorio es tomado como directorio destino de
                     ciertos programas que tienen informacion extra y la
                     necesitan para poder trabajar.

Adicionalmente, hay programas que son muy grandes que reservan un
directorio para ellos con su nombre dentro del directorio /usr/local.
Por ejemplo: Netscape Communicator /usr/local/netscape, KDE (Kommon
Desktop Environment) /usr/local/kde.

9.1.5 LA INSTALACION

El ultimo paso a realizar es la instalacion. Para ello ejecutamos el
siguiente comando:

 ==> make install

Este comando iniciara un proceso de instalacion que se ocupa de copiar
todos los archivos necesarios a el/los directorios destino
especificados. Seguiran una serie de mensajes y luego se dara por
finalizada la instalacion.

  NOTA: Es necesario estar en una sesion con permisos de superusuario
        para poder ejecutar este comando, ya que si no tenemos permiso
        de escritura en el directorio destino, el proceso de
        instalacion abortara con un error. Para esto, podemos iniciar
        una sesion con el usuario root, o ejecutar directamente el
        comando su (superuser), el cual nos pedira la contraseña del
        superusuario y si es correcta, iniciaremos una sesion con
        permisos de superusuario. Una vez finalizada la instalacion,
        podemos retornar a la sesion anterior con el comando exit.

Es posible que cada programa necesite que realicemos ciertas
configuraciones adicionales para hacer que el programa funcione.
Usualmente debemos seguir una serie de instrucciones que son
especificadas en la documentacion del programa. Las configuraciones
tipicas que debemos realizar son edicion del camino de busqueda,
creacion y exportacion de variables de entorno, etc. Todos estos temas
seran tratados en capitulos posteriores.

9.2 EL SISTEMA DE PAQUETES RPM

RPM (RedHat Package Manager) es un sistema de manejo de paquetes de
software muy potente, que puede ser utilizado para construir, instalar,
consultar, verificar, actualizar y desinstalar paquetes de software
individuales. Un paquete consiste de dos partes fundamentales: el
software en si y un encabezamiento que contiene la informacion del
paquete (nombre, version, dependencias, etc).

RPM le otorga al administrador al habilidad de poder actualizar
componentes individuales o sistemas enteros conservando la
configuracion del sistema o paquete, consultar la base de datos de
paquetes para averiguar la locacion de los archivos, paquetes o
informacion relacionada.

RPM es el sistema de manejo de paquetes de Red Hat, pero esto no
significa que solo pueda ser usado en una distribucion Red Hat. Se
desarrollo pensando en ser un sistema de paquetes abiertos, es decir,
para poder ser utilizado en cualquier distribucion. Actualmente, Red
Hat recomienda a otros distribuidores de Linux a usarlo en sus
distribuciones. Hoy, podemos considerar que es el sistema de manejo de
paquetes mas utilizado en la comunidad Linux.

9.2.1 CONVENCIONES EN LOS NOMBRES DE LOS PAQUETES

Un paquete de software RPM construido correctamente tiene la
caracteristica de que su nombre (package.rpm) identifica la siguiente
informacion: el nombre del paquete, su version, la ultima revision de
compilacion y la arquitectura para la cual fue construido. En general
los paquetes son distribuidos en archivos con extension .rpm.

Veamos un ejemplo con el paquete XFree86-3.3.1-14.i386.rpm. El nombre
del paquete es XFree86 y es el sistema grafico de ventanas que se
utiliza en Linux. Su version es la 3.3.1 y es revision 14 de esa
version. La plataforma para la cual fue construido es la Intel 80386 o
superiores. Como vemos, el nombre del archivo mediante el cual se
distribuye el paquete nos puede brindar mucha informacion del mismo.

Es mas, aun, la informacion que posee un paquete internamente. Aunque
el estudio de la estructura interna de un paquete RPM esta, claramente,
fuera del ambito de este manual, podemos destacar que en un paquete
internamente tiene:

 * Archivos ejecutables.
 * Archivos de configuracion.
 * Archivos de documentacion (HTML, man-pages, etc).
 * Archivos miscelaneos relacionados directamente con el paquete.
 * Un registro de los lugares donde se deben instalar los archivos.
 * Un registro de todos los paquetes requeridos (dependencias).

9.2.2 LA BASE DE DATOS DE RPM.

El sistema de manejo de paquetes RPM mantiene una base de datos, local
al sistema, donde se mantienen los datos de todos los paquetes
instalados en el sistema.

Una vez instalado un paquete exitosamente, toda la informacion del
paquete se registra en la base de datos.

9.2.3 MODOS DE OPERACION DE RPM

Todas las operaciones del sistema de manejo de paquetes se realizan con
el programa rpm. El mismo tiene varios modos de operacion, donde cada
uno de ellos posee opciones especiales.

 NOTA: Sobre el sistema de ventanas X-Windows existen varias
       herramientas graficas de manejo de paquetes, que son muy faciles
       de utilizar y muy comodas. Algunas de ellas son: kpackage (para
       el Windows Manager KDE), X Package Management Tool (es provisto
       con las herramientas estandar de la distribucion Red Hat).

Los 4 modos mas importantes de la operacion son:

Modo de Instalacion:

 ==> rpm -i [install-options] <package>

 Este comando instala un nuevo paquete. El siguiente comando actualiza
 un paquete de version mas nueva que la anterior.

 ==> rpm -U [install-options] <package>

 Las opciones de instalacion mas importantes son:

  * --replacefiles: reemplaza todos los archivos, por mas que sean de
                    otros paquetes.

  * --allfiles: instala o actualiza todos los archivos, por mas que no
                exista.

  * --nodeps: no realiza un chequeo de dependencias sobre el paquete a
              instalar.

Modo de consulta:

La forma general de un comando de consulta es:

 ==> rpm -q [query-options]

 Las opciones de consulta mas importantes son:

 * <package-name>: consulta el paquete con ese nombre. Notar que no es
                   el nombre del archivos, sino el nombre del paquete.

 * -a: consulta todos los paquetes.

 * -l: lista los archivos que contiene un paquete.

 * -R: lista las dependencias del paquete.

 * -p <package-file>: consulta un archivo .rpm que no esta instalado.

 * -i: muestra la informacion del paquete: nombre, version, etc.

Modo de verificacion:

El modo de verificacion nos permite comparar la informacion de los
archivos instalados como parte de un paquete con la informacion de los
archivos sacada del paquete original que es guardada en la base de
datos de RPM. Incluyendo otras cosas, el modo de verificacion, compara
el tamaño de los archivos, permisos, tipos, dueños y grupos de cada
archivo. Cualquier discrepancia se muestra en pantalla.

El comando de verificacion es de la siguiente forma:

 ==> rpm -V [verify-options]

 Las opciones de especificacion de paquetes son iguales a las de
 consulta.

Modo desinstalacion

La forma del comando de desisnstalacion es la siguiente:

 ==> rpm -e <package-name>

 Pueden ser especificadas opciones adicionales:

 * --nodeps: no realizar un chequeo de las dependencias. Si algun
             paquete instalado necesita del paquete que estamos
             desinstalando, se borrara igual.

 * --allmatches: remueve todas las versiones del paquete especificado.

9.3 UTILIACION DE LIBRERIAS

Con el objetivo de hacer que los programas sean mas pequeños, los
mismos se desarrollan utilizando el concepto de "librerias
compartidas". Las librerias son colecciones de modulos ya
desarrollados, para ser utilizados en el desarrollo de nuevos
programas. Estas colecciones, de alguna forma, son factorizadas, es
decir se proveen una sola vez y cualquier numero de programas pueden
utilizar su funcionalidad.

 NOTA: O sea, que si tenemos muchos programas que utilizan un mismo
       archivo en comun para funcionar, no es necesario que haya una
       copia del mismo para cada programa que lo utilice. Sino que que
       todos los programas que utilicen ese archivo pueden usar un solo
       archivo que se comparte con el resto de los programas que lo
       utilicen tambien.

En el S.O. Linux, el concepto de librerias compartidas es muy utilizado
por los programadores a la hora de desarrollar el software. A la hora
de instalar un nuevo programa, podemos encontrarnos con la necesidad de
instalar previamente algun conjunto de librerias. Primero veremos
cuales son los lugares donde se encuentran las librerias en nuestro
sistema y luego veremos como se pueden instalar librerias adicionales.

9.3.1 DIRECTORIOS DE LAS LIBRERIAS

Las librerias, en el S.O. Linux, se encuentran distribuidas en varios
lugares. A diferencia de otros S.O., que mantiene todas las librerias
en un lugar centralizado (con las desventajas que esto trae), Linux las
distribuye de acuerdo a unas convenciones muy simples. Los directorios
comunmente utilizados son los siguientes:

 /lib: Son las librerias necesarias para poder ejecutar los programas
       que se encuentran en los directorios /bin y /sbin.

 /usr/lib: Son las librerias que necesitamos para poder ejecutar los
           programas que se encuentran en /usr/bin y /usr/sbin.

 /usr/X11R6/lib o /usr/X11/lib: Son librerias que utiliza el sistema de
                                ventanas X-Windows y los programas que
                                funcionan con el mismo. Usualmente son
                                librerias graficas.

 /usr/local/lib: Este es el directorio que usamos comunmente para
                 instalar las librerias adicionales que nosotros
                 instalamos como parte de algun programa.

9.3.2 INSTALACION DE LIBRERIAS

Las librerias en Linux, en general, son provistas con su codigo fuente,
por las mismas razones que el software es distribuido asi.

El proceso necesario para instalar una determinada libreria puede
variar considerablemente. Hoy, la tendencia es a seguir el mismo
procedimiento que con el software. Es decir que tenemos que seguir los
mismos pasos de "configuracion", "compilacion" e "instalacion"
descriptos en la seccion 9.1. Si la libreria, necesita que sigamos
algun otro proceso de instalacion, deberemos referirnos a su
documentacion y seguir las instrucciones de instalacion que usualmente
son provistas como parte de la distribucion del software.

Una vez realizada la instalacion de la libreria, nos resta realizar un
paso adicional para que puedan ser utilizadas en el sistema. El S.O.
mantiene un "vinculador de tiempo de ejecucion (run time linker)" que
mantiene una base de datos de las librerias disponibles para los
programas. Cuando un programa necesita utilizar una libreria, entra en
juego este vinculador y realiza la "vinculacion" entre el mismo y la
libreria, para que el primero la pueda utilizar. Cuando agregamos una
libreria al sistema, debemos asegurarnos que el vinculador se "entere
de su existencia".

EL ARCHIVO /etc/ld.so.conf

Este archivo mantiene una lista de los directorios donde tenemos
librerias instaladas en el sistema. El contenido de un archivo de estos
es mostrado en la figura 9.2.

 # cat /etc/ld.so.conf
 /usr/i486-linux-libc5/lib
 /usr/X11R6/lib
 /usr/local/lib
 /usr/local/kde/lib

         Figura 9.2: Un archivo /etc/ld.so.conf.

Este archivo mantiene los directorios que son escaneados por el
vinculador de tiempo de ejecucion en busca de librerias instaladas en
el sistema. Normalmente, el vinculador esta configurado para actualizar
la informacion de las librerias cada vez que se inicia el sistema. Por
lo tanto, se puede pensar que para que el vinculador encuentre nuestra
libreria, solo es necesario agregar el directorio donde se instalo la
misma y luego reiniciar el sistema. Ese razonamiento no es erroneo,
pero no es muy practico que digamos.

Linux es un sistema que esta diseñado para evitar ser reiniciado, salvo
situaciones extremas, a diferencia de otros S.O. que necesitan ser
reiniciados por cosas minusculas. Es inaceptable tener que reiniciar el
sistema porque se agrego una libreria al sistema, sobre todo teniendo
en cuenta que Linux es "multiusuario" y si tenemos usuarios conectados
tendremos que desconectarlos del sistema para poder reiniciar, o sin ir
mas lejos pensemos en un sistema que actua como servidor de WWW y que
esta atendiendo pedidos y se lo reinicia sin previo aviso.

Para evitar reiniciar el sistema cada vez que instalamos un nuevo
programa o libreria, Linux posee un comando que le indica al vinculador
de tiempo de ejecucion que refresque la informacion de las librerias
escaneando los directorios nuevamente. Una vez que hayamos editado el
archivo /etc/ld.so.conf, debemos ejecutar el siguiente comando:

 ==> ldconfig

el mismo refrescara las librerias que el vinculador considerara de ahi
en adelante. A partir de eso podemos comenzar a utilizar el programa ya
que el vinculador encontrara al libreria en el momento que el programa
la solicite.

Tanto la ejecucion de este comando como la edicion del archivo
/etc/ld.so.conf se deben hacer con privilegios de superusuario ya que
un usuario ordinario NO DEBE TENER PERMISO para escribir el archivo
/etc/ld.so.conf y el comando ldconfig usualmente no se encuentra
disponible para ser ejecutado por un usuario comun.


CAPITULO 10

MONTANDO SISTEMAS DE ARCHIVOS

Como vimos en capitulos anteriores, todos los archivos en un sistema
Linux se acomodan en un gran arbol: la jerarquia de archivos tiene a
"/" como raiz. Estos archivos pueden estar distribuidos en distintos
dispositivos

Antes de poder utilizar un sistema de archivos, debemos "montarlo"
sobre la jerarquia de archivos. Para ello necesitaremos conocer el
dispositivo a montar y tener disponible un punto de montaje (un
directorio). El comando mount nos sirve para agregar un sistema de
archivos a la jerarquia de archivos. De forma opuesta, el comando
unmount, eliminara la asociacion creada con el comando mount.

10.1 SISTEMAS DE ARCHIVOS Y PARTICIONES

Un sistema de archivos es una coleccion de archivos o directorios en
algun dispositivo, con algun tipo o formato de almacenamiento. Discos
de poca capacidad (por ejemplo: discos flexibles) solo poseen un
sistema de archivos, en cambio los discos grandes pueden tener varias
regiones (particiones), cada una con su sistema de archivos propio.

Existen varias motivaciones por las cuales se trata de particionar los
discos. En el comienzo de Unix, particionar los discos era necesario
porque las estructuras del kernel para mantener los datos de los
archivos y sistemas de archivos no podian direccionar todo el espacio
de almacenamiento disponible. En los sistemas Unix modernos (incluyendo
a Linux) un archivo, potencialmente, puede tener como maximo 2
Gigabytes y un sistema de archivos puede ser tan largo como un Terabyte
(1.000.000 Megabytes). Ningun disco, hoy, puede alcanzar esas
capacidades, por lo que la decision de particionar el disco es
opcional.

Una de las razones por las cuales es adecuado particionar es la
modularidad. Las particiones nos permiten controlar la cantidad de
espacio que asignamos a una dada actividad o tipo de uso de un sistema
de archivos: es usual crear una particion aparte para el directorio
/tmp otra para el directorio /home donde se encuentran los datos de los
usuarios, etc. Las particiones nos otorgan la posibilidad de realizar
un control mas fino sobre las tareas de backup. Los archivos de
solo-lectura y los temporales en general no se tienen en cuenta al
realizar un backup. Manteniendolos en particiones separadas
solucionamos este problema, ya que la tarea de backup toma todo o nada
de la informacion de una particion.

Un caso particular de particionamiento del disco disco lo encontramos
en la particion utilizada para realizar el intercambio de datos cuando
no queda memoria disponible (swap). Linux trata el espacio swap como
una particion separada del sistema de archivos principal. La particion
de swap esta organizada de forma contigua para poder ser accedida
eficientemente, por lo que requiere una estructura distinta a la
utilizada en el sistema de archivos principal. Esta es la causa por la
cual el espacio de intercambio se mantiene en una particion especial.

10.2 SINTAXIS DEL COMANDO MOUNT

La forma estandar del comando mount es la siguiente:

 ==> mount -t type device dir

Un comando de este tipo le comunica al kernel que monte el sistema de
archivos de tipo "type" que se encuentra en el dispositivo "device"
sobre el directorio "dir". Los contenidos del directorio "dir" (si
existen) se vuelven invisibles, mientras el sistema de archivos se
mantenga montado.

La mayoria de los dispositivos se indican por un nombre de archivo, por
ejemplo: /dev/hdb (la unidad IDE esclava-primaria), /dev/hda1 (la
primera particion de la unidad de disco IDE master-primaria),
/dev/cdrom (la unidad CD-ROM) o /dev/fd0 (la primera unidad de disco
flexibles del sistema).

Los programas mount y unmount mantienen una lista de los sistemas de
archivos actualmente montados en el archivo /etc/mtab. Si se ejecuta el
comando mount sin argumentos, la informacion contenida en ese archivo
es mostrada como salida.

10.3 MONTANDO SISTEMAS DE ARCHIVOS

Para poder montar distintos sistemas de archivos debemos conocer: el
dispositivo donde se encuentra el sistema de archivos, el tipo del
sistema de archivos y el punto de montaje. Ademas de esto debemos tener
los permisos de superusuario o tener permiso de montaje de usuario
ordinario (esto se explica en la seccion 10.5.3).

Una vez que conocemos toda esa informacion podemos utilizar el comando
mount para montar el sistema de archivos en la jerarquia. Un tema muy
delicado es el de los tipos de sistemas de archivos, ya que existen una
gran variedad de sistemas de archivos, cada uno con su formato propio.
Linux es capaz de manipular una gran cantidad de sistemas de archivos
eficientemente, pero un item que usualmente confunde a los usuarios es
el hecho de que para poder montar sistemas de archivos de un
determinado tipo es necesario tener compilado el kernel con el soporte
para ese tipo de sistema de archivos. En un capitulo posterior veremos
como hacer para agregar al kernel el soporte para distintos sistemas de
archivos. Por ahora supondremos que el kernel es capaz de entender
cualquier sistema de archivos disponible.

10.3.1 TIPOS DE SISTEMAS DE ARCHIVOS

SISTEMAS DE ARCHIVOS FAT

Si queremos accedera a archivos de particiones que contienen sistemas
de archivos basados en FAT, debemos utilizar el tipo "msdos". En este
caso los nombres de los archivos repetaran el formato de MS-DOS
(windows 3.x), o sea nombres de 8 caracteres con extension de 3.

Podemos utilizar el tipo "vfat" para montar sistemas de archivos de
Windows 95/98. Los kernels de versiones 2.0.x no soportan las
extensiones de Microsoft para nombres largos, por lo que veremos los
archivos con el formato de nombres de MS-DOS. A estos kernels es
posible aplicarles un patch, disponible gratuitamente en Internet, para
poder ver los nombres largos. Por suerte los kernels 2.2.x ya tiene ese
soporte integrado por lo que no debemos realizar ninguna tarea
adicional.

El siguiente comando montara el sistema de archivos de Windows 95 que
se encuentra en la particion 2 del primer disco de la maquina, en el
directorio /mnt/win95.

 ==> mount -t vfat /dev/hda2 /mnt/win95

Es posible montar discos flexibles de cualquiera de estos dos tipos. En
general el dispositivo de la disquetera es /dev/fd0 o /dev/floppy. El
siguiente comando nos muestra como podemos montar un diskette MS-DOS.

 ==> mount -t msdos /dev/fd0 /mnt/floppy

SISTEMAS DE ARCHIVOS NTFS

Anteriormente, dijimos que un sistema Linux puede coexistir con Windows
NT en una maquina. Aicionalmente, podemos montar un sistema de archivos
NTFS (el sistema de archivos de Windows NT) como parte de nuestra
jerarquia. Para ello podemos utilizar el siguiente comando:

 ==> mount -t ntfs /dev/hda1 /nt

 NOTA: El soporte de NTFS del kernel (2.2.5) permite leer corectamente
       informacion, pero el soporte para escritura se encuentra en una
       etapa experimental y es muy peligroso activarlo, ya que podemos
       romper la estructura del sistema de archivos NTFS y volverlo
       inutilizable. Se recomienda montar estos sistemas de archivos
       como solo lectura.

MONTANDO CD-ROM'S (SISTEMA DE ARCHIVOS ISO9600)

El sistema de archivos estandar utilizado en los cd-rom que contiene
datos es el ISO9600, conocido previamente como "High Sierra Filesystem"
(hsfs), por lo que en otros Unix es conocido de tal forma.

Como el medio de almacenamiento de cd-rom es inherentemente de solo
lectura, los cd-rom seran siempre montados como solo lectura. El
comando para montar un cd-rom puede ser:

 ==> mount -t iso9600 /dev/cdrom /mnt/cdrom

10.4 DESMONTANDO SISTEMAS DE ARCHIVOS

Una vez que trabajamos con el sistema de archivos y ya no lo
necesitamos podemos desmontarlo. Hay sistemas de archivos que se montan
automaticamente al iniciarse y permanecen montados hasta que el sistema
se baja. Mas adelante veremos como se pueden configurar los sistemas de
archivos para que se comporten de esta manera.

Los medios removibles (discos flexibles, cd-rom's, etc) y en ocasiones
discos y particiones son montados temporariamente para leer o escribir
informacion y luego son desmontados.

El comando umount (unmount) nos permite desmontar un sistema de
archivos. La informacion necesaria para desmontar un sistema de
archivos puede ser el dispositivo o alternativamente el directorio
donde esta montado. Por lo tanto podemos desmontar el cd-rom que
montamos en la seccion anterior con cualquiera de los siguientes
comandos:

 ==> umount /dev/cdrom

 ==> umount /mnt/cdrom

 Observaciones:

 * Un sistema de archivos no puede ser desmontado si se encuentra
   "ocupado", esto es, por ejemplo, cuando existen archivos del mismo
   que se encuentran abiertos o cuando algun proceso tiene como
   directorio de trabajo algun directorio del sistema de archivos. El
   comando fuser nos sirve para averiguar que usuarios, y que procesos,
   estan utilizando un determinado archivo o sistema de archivos.
   Adicionalmente nos permite matar estos procesos, para poder
   desmontar el sistema de archivos.

 * Cuando un sistema de archivos se encuentra montado, cierta
   informacion vital de la locacion de los archivos en ese sistema de
   archivos, se mantiene en memoria con el kernel. Si removemos el
   medio fisico sin realizar el umount puede suceder que la informacion
   que se encuentra en memoria se pierda, y el estado del sistema de
   archivos quede inconsistente. El proposito de la operacion umount es
   volcar toda la informacion del sistema de archivos, que se encuentra
   en memoria, al medio fisico, para que todo quede en un estado
   consistente.

10.5 EL ARCHIVO /etc/fstab

El archivo /etc/fstab (file system table) es uno de los archivos mas
importantes en lo que concierne a la administracion del sistema. El
mismo contiene lineas describiendo que dispositivos son usualmente
montados, con que opciones y donde se montan los mismos. Contiene,
ademas, la informacion de los sistemas de archivos que deben ser
montados automaticamente al iniciarse el sistema.

Es tarea del adminsitrador del sistema editar y mantener este archivo.
Cada sistema de archivos se escribe en una linea separada. Cada linea
contiene varios campos y estos son separados por tabs o espacios. Como
ejemplo, vemos un archivo fstab en la figura 10.1.

 # Device or NFS         Mount Point            Type     Options

 /dev/hda3               /                      ext2     defaults             1 1
 /dev/hda2               /mnt/win95             vfat     defaults             0 0
 /dev/hda4               swap                   swap     defaults             0 0
 /dev/fd0                /mnt/floppy            vfat     user,noauto          0 0
 /dev/hdb                /mnt/cdrom             iso9600  ro,user,noauto,noide 0 0
 none                    /proc                  proc     defaults             0 0
 /dev/hda1               /mnt/nt                ntfs     unmask=022,ro        0 0

          Figura 10.1: Un archivo /etc/fstab con informacion de los
                       sistemas de archivos.

10.5.1 CAMPOS DE CADA ENTRADA

Device or NFS: Especifica el dispositivo donde se encuentra el sistema
               de archivos. En caso de ser un sistema de archivos en
               red (NFS), no se especifica un dispositivo, sino que
               debemos poner el nombre del host, del directorio que se
               encuentra compartido.

Mount Point: Punto de montaje. Es el directorio que forma parte de la
             jerarquia, donde queremos montar el sistema de archivos.
             Notemos que estos directorios solo pueden ser
             especificados con rutas absolutas. En caso de ser una
             particion swap, el punto de montaje es nulo y se
             especifica con swap o none.

Type: Es el tipo de sistema de archivos que se encuentra en el
      dispositivo. Puede ser: msdos, vfat, ext2, minix, iso9600, swap,
      etc. El kernel debe tener compilado el soporte para cada sistema
      de archivos que especificamos.

Options: Este campo es una serie de opciones separadas por comas. Cada
         opcion tiene un comportamiento determinado y las opciones
         varian de acuerdo al tipo de sistema de archivos. Explicaremos
         las mas comunmente utilizadas:

         rw,ro: La primera (read/write) monta el sistema de archivos en
                 modo lectura/escritura. La segunda ro (read-only)
                 especifica que se montara como solo lectura.

         auto,noauto: Especifican si el sistema de archivos se montara
                      al iniciar el sistema o no.

         user,nouser: Especifican si el sistema de archivos puede ser
                      montado por el usuario ordinario o no.

         defaults: Especificamos que tome las opciones predeterminadas,
                   entre otras: rw,auto,nouser.

10.5.2 USO DEL ARCHIVO FSTAB

Este archivo, usualmente es utilizado en tres formas:

 1- El comando mount -a (all), usualmente ejecutado en los scripts de
    inicio del sistema, monta todos los sistemas de archivos
    especificados en el archivo /etc/fstab, salvo las que tengan la
    opcion noauto. En general los medios removibles (discos flexibles,
    cd-rom's, discos ZIP, etc.) son especificados con la opcion noauto.

 2- Cuando montamos un sistema de archivos que se encuantra
    especificado en el archivo /etc/fstab, basta con especificar el
    dispositivo a montar o el punto de montaje. El comando mount
    buscara el resto de la informacion en el archivo. Por ejemplo,
    suponiendo que nuestro archivo fstab es el de la figura 10.1 y
    queremos montar el cd-rom, podemos ingresar cualquiera de los
    siguientes comandos:

     ==> mount /dev/cdrom

     ==> mount /mnt/cdrom

 3- Para definir que sistema de archivos pueden ser montados por
    usuarios ordinarios. Ver seccion siguiente.

10.5.3 PERMITIENDO MONTAR SISTEMAS DE ARCHIVOS A UN USUARIO ORDINARIO

El comando mount debe ser utilizado solo por el administrador del
sistema (root). Asi podemos tener seguridad en el sistema. No queremos
que los usuarios ordinarios puedan montar y desmontar a gusto nuestros
sistemas de archivos, pero seria una restriccion muy grande que los
usuarios comunes no puedan montar, por ejemplo, un diskette. Para
solucionar esto, sin comprometer la seguridad del sistema, el
adminstrador especifica en el archivo /etc/fstab cuales son los
sistemas de archivos que un usuario puede montar, utilizando la opcion
user. El usuario puede, luego, montar el sistema de archivos, pero
limitado al tipo, punto de montaje y opciones especificadas por el
adminstrador en el archivo /etc/fstab.


CAPITULO 11

EL KERNEL Y LOS MODULOS

11.1 ¿QUE ES EL KERNEL?

El kernel es el organizador principal del S.O. Linux. El kernel
planifica la ejecucion de los procesos y se asegura de que cada uno de
ellos obtenga una tajada "justa" de tiempo de procesador; realiza todo
el manejo de memoria necesario para que los procesos puedan trabajar;
provee una interfaz agradable y portable para que los procesos y
programas de usuario puedan interactuar con el hardware; maneja todo lo
respectivo a almacenamiento de datos en discos; realiza la supervision
de las transmisiones de datos entre la memoria y los dispositivos
perifericos y debe servir todos los pedidos de acceso a hardware de los
procesos.

El kernel es la porcion del S.O. Linux que se encuentra residente en
memoria. Comparado a muchos S.O. de "mainframes", el kernel de Linux
provee una funcionalidad relativamente pequeña (aunque aumentando dia a
dia). De todas formas, comparado a otros S.O. de microcomputadoras,
como lo puede ser MS-DOS, Windows 95, etc., el kernel de Linux tiene un
gran repertorio de servicios.

El kernel nunca realiza alguna tarea directamente para el usuario; los
servicios basicos del kernel son provistos mediante utilidades que
establecen la interfase entre el usuario y el kernel.

El kernel de Linux se ocupa, principalmente, de las siguientes tareas:

 Manejo de memoria: El subsistema de manejo de memoria es una de las
                    partes mas importantes del S.O. Desde los primeros
                    dias de la computacion, ha habido una necesidad de
                    tener mas memoria de la disponible fisicamente en
                    un sistema. Se han desarrollado varias estrategias
                    para sobrepasar esta limitacion, y la mas exitosa
                    de todas, sin dudas, ha sido la memoria virtual. La
                    memoria virtual hace parecer que el sistema tiene
                    mas memoria que la fisica usando almacenamiento en
                    disco para ampliar la misma. La ventaja de esto es
                    que podemos ejecutar mas procesos que los que
                    quepan en memoria en un instante dado de manera muy
                    eficeinte.

 Procesos: Un proceso es un programa de computadora en accion, una
           entidad dinamica, su estado cambia constantemente a medida
           que es ejecutado. El kernel tiene la responsabilidad de
           comenzar los procesos, planificar su ejecucion de manera
           justa, enviarlos a espacio de intercambio (swap) cuando no
           hay mas memoria disponible y traerlos nuevamente a memoria
           cuando se libere espacio para que puedan seguir
           ejecutandose, otorgarles recursos y servir sus pedidos de
           interaccion con los dispositivos.

 Mecanismo de intercomunicacion entre procesos: Los procesos se
     comunican entre si y con el kernel para coordinar y sincronizar
     sus actividades. Linux soporta un numero de Mecanismos de
     Comunicacion entre Procesos (Inter-Process Communications - IPC),
     las señales y las cañerias son dos de ellos. A su vez. Linux posee
     otro mecanismo muy potente de comunicacion entre procesos que son
     los sockets, este mecanismo es muy importante para la
     implementacion de los protocolos de red utilizados en varios
     sistemas. Adicionalmente, se tiene colas de mensajes, semaforos y
     memoria compartida.

 Manejadores de dispositivos (device drivers): Uno de los objetos
     principales de un S.O. es ocultar a los usuarios las
     peculiaridades especificas del hardware sobre el cual se ejecuta.
     El CPU (Central Processing Unit) no es el unico dispositivo de
     hardware "inteligente" en una computadora. Cada dispositivo posee
     su controladora en hardware que conoce perfectamente las
     caracteristicas del mismo y puede manejar su operacion
     satisfactoriamente. El software que maneja y controla una
     controladora de hardware se conoce como manejador de dispositivo
     (device driver). El kernel de Linux posee una gran cantidad de
     manejadores de dsipositivos y les encarga a ellos el tratamiento
     de bajo nivel de los dispositivos, pero siempre supervisando su
     tarea.

 Sistemas de archivos: La habilidad de manejar los sistemas de archivos
     en necesaria para poder almacenar y recuperar informacion de los
     medios de almacenamiento. En el pasado, cada sistema manejaba su
     propio sistema de archivos. Una de las potencialidades de Linux es
     el soporte que tiene para una gran variedad de sistemas de
     archivos distintos. Esta caracteristica hace de Linux un sistema
     altamente flexible y hace posible que coexista con otros S.O.

 Redes: El trabajo en red y Linux son casi sinonimos. En sentido real,
        Linux es un producto de Internet o la World Wide Web (WWW).
        Linux posee soporte nativo para varios protocolos de red, como
        lo son TCP/IP, AppleTalk, etc.

El kernel, internemente, esta dividido en modulos que se ocupan cada
uno de una tarea en especial. Una sobre-simplificacion de la estructura
del kernel, se muestra en la figura 11.1.

                         /--------------------\
                        | Programas de usuario |\
                         \--------------------/  |
                            \---|---|---|-------/
                                |   |   |                    PROGRAMAS
 # # # # # # # # # # # # # # # #|# #|# #|# # # # # # # # # # # # # # # # # # # # #
                                |   |   |                     KERNEL
      _________________________\|/_\|/_\|/___________________________________
     |      .            Interfaz de llamdas al sistema                      |
      °°°°°°|°°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°°°|°°°°°°°°°°°°°°°°°|°°°°°
      _____\|/_____        _____\|/______       ____\|/_______     ___\|/__________
     | Manejo de   |      | Manejador de |     | Manejador de |   | Servicios de   |
     | sistemas de |      |  memoria     |     |  Procesos    |   | red abstractos |
     | archivos    |       °°°°°°°°°°°°°°       °°°°°°°°°°°°°°    |  (sockets)     |
     | virtuales   |                                               °°°°°°°|°°°°°°°°
      °°°°°°|°°°°°°                                                      \|/
           \|/                                                    |°°°°°°°°°°°°°°°°°|
     |°°°°°°°°°°°°°|                                              | Manejadores del |
     | Varios      |                                              |protocolo TCP/IP |
     | manejadores |                                              |_________________|
     | de sistemas |______________                                        |
     | de archivos |              °\                                     \|/
      °°°°|°°°°°°°°                 |                             |°°°°°°°°°°°°°°°°|
         \|/                       \|/                            | Manejador de   |
     |°°°°°°°°°°°°°|     |°°°°°°°°°°°°°°°°°°°°°|                  | tarjeta de red |
     | Manejador   |     | Manejador de        |                  |  Ethernet      |
     | de discos   |     | Unidad de diskettes |                   °°°°°°°|°°°°°°°°
     | rigidos IDE |     |                     |                          |
      °°°°|°°°°°°°°       °°°°°°°°°°|°°°°°°°°°°                           |
          |                         |                                     |               KERNEL
 # # # # #|# # # # # # # # # # # # #|# # # # # # # # # # # # # # # # # # #|# # # # # # # # # # # #
          |                         |                                     |               HARDWARE
         \|/                       \|/                                    |
  |°°°°°°°°°°°°°°°°°°|     |°°°°°°°°°°°°°°°°°°°°°|                       \|/
  | Disco Rigido IDE |     | Unidad de diskettes |                 |°°°°°°°°°°°°°°°°°°|
  |__________________|     |_____________________|                 | Tarjeta Ethernet |
                                                                    °°°°°°°°°°°°°°°°°°

                Figura 11.1: Partes importantes del kernel.

11.2 LA INTERACCION

Como dijimos anteriormente, en Linux, a diferencia de otros Unix, ni el
programador ni el usuario interactuan directamente con el kernel.
Existen dos mecanismos que son utilizados para interactuar con el S.O.
Ambos terminan ejecutando "llamadas al sistema" (system calls) que son
funciones que el kernel provee como servicios, y cada una de ellas
tiene un rol predeterminado, por ejemplo: abrir un archivo, iniciar un
proceso, mandar un mensaje a otro proceso, etc. Si la comunicacion
usuario-sistema operativo se realizara mediante llamadas al sistema,
seria todo muy engorroso y tedioso, ya que las mismas implementan
funciones de muy bajo nivel. Para, por ejemplo, listar los contenidos
de un directorio tendriamos que ejecutar una gran cantidad de llamadas
al sistema explicitamente, lo que es inviable para un usuario.

Las librerias del sistema y los programas de usuario nos brindan una
interfase mas amigable para poder comunicarnos con el sistema.

11.2.1 LAS LIBRERIAS DEL SISTEMA

Las librerias del sistema definen un conjunto de funciones mediante las
cuales las aplicaciones pueden interactuar con el kernel y que
implementan la mayoria de la funcionalidad del S.O. que no necesita los
privilegios que posee el codigo del kernel.

La interfaz del S.O., visibles a las aplicaciones, no es mantenida
directamente por el kernel, sino que las aplicaciones hacen llamadas a
las librerias del sistema que luego llaman a los servicios del S.O. si
es necesario.

Las librerias del sistema proveen muchos tipos de funcionalidad. En el
nivel mas simple, permiten a las aplicaciones realizar pedidos de
servicios al kernel. Las librerias pueden, tambien, proveer versiones
mas complejas de las llamadas al sistema. Por ejemplo: las funciones de
libreria del lenguaje C de manejo de archivos, estan todas
implementadas en las librerias del sistema, permitiendo asi un control
mas avanzado de entrada-salida de archivos que aquel que el kernel
provee. Las librerias del sistema tambien contiene rutinas que no
corresponden a las llamadas al sistema como lo pueden ser algoritmos de
ordenamiento, funciones matematicas, etc.

11.2.2 LAS UTILIDADES DEL SISTEMA

Las utilidades del sistema o programas del usuario, son programas que
realizan tareas individuales y especializadas. Algunas utilidades del
sistema se invocan una unica vez para inicializar y configurar algun
aspecto del sistema, otras; conocidas como "demonios", se ejecutan
permanentemente en "background" y manejan tareas de conexiones de red,
actualizacion de "archivos de log", aceptacion de pedidos de inicio de
sesion, etc.

No todas las utilidades del sistema sirven para adminsitrar puntos
claves del sistema. El entorno del S.O. Linux contiene un gran numero
de utilidades estandar para realizar tareas simples, de todos los dias,
como son listar directorios, mostrar el contenido de un archivo, etc.
Por mas que estas utilidades no realicen tareas del S.O. en si son una
parte muy importante del S.O. Linux.

11.3 ¿QUE SON LOS MODULOS?

El kernel de Linux es un "kernel monolitico". Esto quiere decir que es
un unico y largo programa donde todos los componentes funcionales del
mismo tiene acceso a todas las estructuras de datos internas y sus
rutinas. Esta caracteristica evidencia una falta de modularidad en el
diseño del kernel. Por ejemplo, si queremos agregar un dispositivo al
sistema, digamos una tarjeta de red, y el manejador de dispositivo no
se encuentra compilado en el kernel, tendremos que volver a compilar
"TODO" el kernel, que, como veremos mas adelante, es un proceso que
consume mucho tiempo.

Para evitar estas situaciones se aplica una estrategia parecida al uso
de librerias compartidas por los programas de usuario en tiempo de
ejecucion. Una gran cantidad de funcionalidad del kernel puede ser
compilada como "modulos" y el kernel puede cargar y descargar los
mismos a medida que los necesita. El kernel no necesita saber que
modulos van a ser cargados, los mismos son verdaderamente componentes
independientes.

Los modulos se cargan bajo demanda, es decir cuando son necesitados
para satisfacer el pedido del algun proceso, y se ejecutan en modo
privilegiado como todo el codigo del kernel de Linux, y, como
consecuencia tienen acceso completo a las capacidades del hardware de
la maquina donde se ejecutan.

Teoricamente, no existe ninguna restriccion en las tareas que un modulo
debe realizar; tipicamente, un modulo puede implementar un manejador de
dispositivo, un sistema de archivos o un protocolo de red.

Existen muchas razones por las cuales es conveniente la utilizacion de
modulos del kernel.

El codigo de Linux es gratis, por lo tanto cualquier persona que quiera
desarrollar un nuevo manejador de dispositivos puede insertarlo en el
kernel, compilarlo y reconstruir el kernel, instalarlo y reiniciar el
sistema con la nueva funcionalidad, pero esta tarea se puede volver
altamente tediosa ya que cada vez que la persona modifique el manejador
de dispositivo debera reconstruir e instalar el kernel para poder
testearlo. Si se utilizan modulos, se puede compilar solamente el
modulo y ser insertado y eliminado del kernel sin necesidad, siquiera,
de reiniciar el sistema !! :)

Finalmente, los modulos del kernel permiten al sistema Linux ser
configurado con un kernel minimo estandar sin ningun manejador extra
formando parte del mismo. Cualquier modulo que el usuario necesite
puede ser cargado explicitamente al iniciarse el sistema o cargado
automaticamente por el sistema al realizarse una demanda y descargado
cuando el sistema detecte que ya no se necesita.

11.4 PERSONALIZANDO EL KERNEL

Una de las caracteristicas mas importantes del S.O. Linux es su
flexibilidad, ya que es posible que podamos "poner a punto" el kernel y
hacerlo a la medida de nuestro sistema, algo es totalmente imposible en
otros S.O. comerciales.

El hecho de que el S.O. Linux se distribuye con su codigo fuente
completo, hace que podamos elegir que queremos que forme parte del
kernel y que queremos dejar afuera. Por ejemplo: Linux posee una gran
cantidad de manejadores de dispositivos SCSI, pero si nosotros no
poseemos ningun dispositivo de este tipo, entonces podemos hacer que el
codigo de estos manejadores no se compile ni se incluya en la
construccion del kernel, obteniendo asi un kernel mas pequeño que
ocupara menos memoria. Ya que, como dijimos antes, el kernel es la
parte del S.O. que se encuentra residente en memoria, es importante
reducir el tamaño del mismo para liberar mas memoria para los procesos.
Gracias a esta caracteristica, Linux exige mucha menor cantidad de
memoria para trabajar que otros S.O. Por esto es totalmente viable
configurar un kernel minimo, para trabajar, por ejemplo, en una maquina
Intel 80386 con 2 Mb de memoria Ram.

La personalizacion del kernel es una tarea que exige que tengamos un
alto grado de conocimiento de las caracteristicas del hardware y de los
servicios que necesitamos que funcionen en nuestro sistema. Un punto
clave en la personalizacion del kernel es la configuracion del mismo.

11.4.1 ELIGIENDO LA CONFIGURACION ADECUADA

   NOTA: Suponiendo que tenemos las fuentes del kernel instaladas
         correctamente, las mismas se encontraran en el directorio
         /usr/src/linux y todos los comandos que se muestran en la
         discusion que sigue deben ser ejecutados en ese directorio,
         salvo que se indique lo contrario. En la seccion 11.5.2 se dan
         las instrucciones para realizar la instalacion de las fuentes
         del kernel, ya sea porque no se encuentran instaladas o porque
         queremos instalar una nueva version.

Cuando configuramos el kernel, estamos eligiendo los servicios que
queremos que formen parte del mismo. Existen varias formas de realizar
esta configuracion. Las mismas son:

make config Solo necesita que tengamos corriendo la shell bash. Ejecuta
             un script que nos va realizando una serie de preguntas. Se
             vuelve un proceso tedioso y no tenemos forma de volver
             atras en caso de un error.

make menuconfig Es una interfaz basada en menues de configuracion.
                 Tenemos un menu principal que se divide en sub-menus
                 de acuerdo a una serie de items. Es mucho mas comodo
                 de utilizar y no requiere interfaz grafica.

make xconfig Solo para aquellos que puedan ejecutar el sistema X
              Windows. Es una interfaz basada en ventanas y botones. Es
              mucho mas comoda para trabajar.

En base a las caracteriticas de nuestro sistema, debemos elegir una
herramienta de configuracion de las tres enumeradas anteriormente y asi
comenzar la configuracion.

ELECCIONES DE LAS OPCIONES

Sin importar de que herramienta usemos para configurar el kernel,
tendremos que seleccionar una opcion para cada item del kernel. Cada
item posee una opcion "y" (yes) y otra "n" (no). Algunas poseen una
opcion "m" (module) que significa que se compilara ese item pero no
directamente dentro del kernel, sino como un modulo independiente.

A continuacion describiremos las opciones basicas a tener en cuenta al
momento de compilar el kernel. Esta lista, obviamente, es no exhaustiva
y no prentende ser una guia precisa de la configuracion de un kernel,
sino que trata de ser una ayuda para un novato a la hora de configurar
un kernel.

CODE MATURITY LEVEL OPTIONS: El S.O. Linux se encuentra en constante
evolucion. Por lo tanto siempre existen caracteristicas que se
encuentran en un estado experimental. Lo que quiere decir que algunas
cosas no se encuentran totalmente testeadas y pueden ser peligrosas
para el sistema. Podemos elegir que el configurador nos deje o no
agregar caracteristicas experimentales al kernel. En general, las
caracteristicas experimentales son utilizadas por desarrolladores y se
recomienda que los usuarios novatos las dejen de lado.

PROCCESOR TYPE AND FEATURES: Aqui configuramos el tipo de procesador de
nuestro sistema. Otro item importante es si deseamos emulacion de
instrucciones matematicas; maquinas superiores a 486 SX poseen
coprocesador matematico en hardware, por lo que si tenemos una maquinas
de estas debemos contestar que no.

LOADABLE MODULE SUPPORT: Aqui especificamos si queremos soporte para
modulos en nuestro kernel. Si vamos a compilar algun servicio como
modulo es indispensable responder "y" a la pregunta Enable lodable
module support ?.

GENERAL SETUP: En esta opcion elegimos parametros generales de nuestro
sistema. Elegimos si queremos soporte para trabajar en red, soporte
para dispositivos PCI, soporte para puertos paralelos (indispensable
para instalar una impresora, o cualquier dispositivo que utilice el
puerto paralelo) y otro items avanzados como lo son Advanced Power
Management (para computadoras portatiles), mecanismos de comunicacion
entre procesos y soporte para distintos formatos de archivos
ejecutables.

PLUG AND PLAY SUPPORT: Si tenemos algun dispositivo periferico que sea
compatible con la norma Plug and Play, debemos contestar "y" al item
Plug and Play support.

BLOCK DEVICES: En esta seccion elegimos el tipo de los dispositivos de
almacenamiento de archivos que vamos a utilizar, como por ejemplo, si
queremos soporte para unidad de diskettes, para discos rigidos IDE,
CD-ROM's IDE/ATAPI, dispositivos de cinta magnetica, soporte para
discos ULTRA-DMA, y otros dispositivos de bloque avanzados. Si estamos
desorientados de que elegir se recomienda soporte para discos IDE,
diskettera normal, CD-ROM's ATAPI y dejar el resto de las opciones
predeterminadas.

NETWORKING OPTIONS: Editar solo si necesitamos soporte para trabajar en
red. Esta seccion esta llena de opciones avanzadas que en general, solo
son seteadas por un adminsitrador de red. Sin embargo, podemos optar en
algunos items. Si queremos soporte para trabajo en red, debemos
asegurarnos de que el item TCP/IP Networking este seleccionado. El
resto de las opciones podemos dejarlas en su estado predeterminado, a
no ser que sepamos lo que estamos haciendo !!! Si nececitamos
conectividad con maquinas corriendo Novell/Netware debemos seleccionar
el soporte para protocolo IPX.

SCSI SUPPORT: Solo si tenemos algun dispositivo SCSI para configurar.
En esta seccion hay una gran variedad de dispositivos para elegir.
Debemos averiguar que marca y modelo es el nuestro y que
caracteristicas posee para seleccionar el adecuado. Podemos elegir que
el manejador de dispositivos se compile como modulo si no sera
frecuentemente utilizado.

NETWORK DEVICE SUPPORT: En esta seccion seleccionamos que tipo de
interfases de red instalaremos en nuestro sistema. Hay soporte para una
gran cantidad de tarjetas Ethernet, tanto ISA, VLB o PCI. Tenemos
soporte para los dispositivos Frame Relay, FDDI, etc. Si vamos a
conectar dos maquinas mediante un cable debemos elegir PLIP (cable
paralelo) o SLIP (cable serie). Para este ultimo tambien podemos elegir
soporte para PPP (Point to Point Protocol), el cual es indispensable si
queremos realizar conexiones a Internet mediante un ISP (Internet
Service Provider) Proveedor de Servicios Internet.

CHARACTER DEVICES: Aqui seleccionamos que dispositivos de caracter
queremos utilizar. Se recomienda elegir consolas virtuales, soporte
para puertos serie estandar, soporte para impresora en puerto paralelo,
soporte para mouse (no serial) en caso de tener un mouse PS/2,
Logitech, etc.

FILESYSTEMS: Esta es una de las secciones mas importantes de la
configuracion del kernel. Aqui elegimos que tipos de sistemas de
archivos podran ser accedidos mediante nuestro kernel. Es indispensable
el soporte para ext2fs que es el sistema de archivos de Linux. Se deben
elegir FAT y VFAT para poder leer y escribir sistemas de archivos de
MS-DOS y Windows 95 respectivamente, el sistema de archivos ISO9660
para leer CD-ROM's de datos, las extensiones Joliet para CD-ROM's de
Microsoft nos permiten entender el formato de nombres largos de los
CD-ROM's que tienen este formato; el soport para NTFS nos permite leer
informacion de los sistemas de archivos de Windows NT; los demas son
sistemas de archivos raramente utilizados y, es preferible
desactivarlos, si no tenemos la necesidad de utilizarlos. El codigo
para poder entender los sistemas de archivos adicionales se suele
compilar como modulos ya que no son utilizados constantemente y podemos
aprovechar para poder reducir el tamaño del kernel.

NATIVE LANGUAGE SUPPORT: En esta seccion podemos elegir que tipo de
lenguaje nativo queremos utilizar. En general se seleccionan las
opciones Codepage 437, Codepage 850 y NLS ISO-8859-1 (Latin 1) para
nuestro pais y paises con lenguajes similares. Los demas codigos de
paginas y de caracteres se utilizan para otros lenguajes: hebreo,
turco, griego, arabe, etc.

SOUND: En esta seccion seleccionamos si queremos o no soporte para
tarjeta de sonido y en caso de ser afirmativa la respuesta elegimos
para que tipo de tarjeta queremos tener soporte. Las tarjetas mas
conocidas y utilizadas son las tarjetas Sound Blaster, Pro Audio
Spectrum, Microsoft Sound System, Ensoniq Soundscape, etc. Es necesario
aclarar que el driver de Sound Blaster es solo para tarjetas que son
100% compatibles con Sound Blaster, que no es el caso de la mayoria de
las tarjetas de sonido genericas que se venden para computadoras
personales. Existen muchisimos modelos que claman ser compatibles Sound
Blaster, pero nos engañan, ya que la compatibilidad la emulan por
software cargando un manejador de dispositivo residente (que solo
funciona con MS-DOS o Windows) que se comunica con la tarjeta. En
Linux, obviamente no podremos cargar este manejador y tampoco podremos
hacer funcionar la tarjeta con el manejador de Sound Blaster. Sin
embargo, algunas de estas tarjetas son compatibles con MAD16 y
funcionan perfectamente con este manejador. Encontramos, tambien
soporte para muchas otras tarjetas menos conocidas que las nombradas
anteriormente, y ademas soporte para poder trabajar con MIDI. Se
recomienda compilar los manejadores que necesitemos como modulos ya que
resulta muy practica y facil la instalacion y la configuracion
posterior de la tarjeta de sonido.

 NOTA: Cada item posee un cuadro de ayuda donde se explica exactamente
       para que sirve. En caso de desorientacion o desconociemiento se
       recomienda LEER la explicacion que alli se encuentra. En caso de
       dudas, dejar la opcion predeterminada.

CODIGO INTEGRADO EN EL KERNEL VS MODULOS

Cuando debemos decidir si un item debe ser compilado como parte del
kernel o como modulo independiente debemos tener en cuenta los
siguientes puntos:

 * Si el servicio va a ser utilizado infrecuentemente y su eficiencia
   no es critica para el funcionamiento del sistema, entonces nos
   conviene que se instale como modulo, ya que no ocupara memoria
   mientras no se necesite.

 * Hay servicios que es necesario que se encuentren instalados al
   iniciarse el sistema. En estos casos es conveniente que se instalen
   como parte del kernel, ya que los modulos se suelen cargar despues
   de que el sistema se inicio y consecuentemente luego de que fuera
   necesitado.

 * Cuando un servicio se compila como modulo tenemos la ventaja de que
   no ocupara espacio innecesario, pero tenemos la desventaja de que
   cuando queremos utilizar el modulo tenemos una sobrecarga. Cuando
   queremos utilizar un servicio que ha sido compilado como modulo,
   debemos cargarlo explicitamente o el mismo puede ser configurado
   para ser cargado automaticamente, pero de todas formas, el kernel
   debe realizar una serie de operaciones para vincular los modulos
   dinamicamente y cargarlos para que puedan ser utilizados. Estas
   operaciones no son necesarias cuando compilamos el servicio como
   parte del kernel.

 * Si el tamaño del kernel nos condiciona rigidamente, entonces debemos
   utilizar los modulos tanto como sea posible. Es normal configurar un
   kernel que haga uso intensivo de modulos y lograr que el tamaño del
   mismo ronde los 400 K.

11.4.2. COMPILANDO EL KERNEL

Luego de que hayamos configurado nuestro kernel pasamos a la etapa
donde construimos el mismo. Esta etapa es un proceso facil de realizar
(desde el punto de vista del usuario), pero, en contrapartida, nos
lleva mucho tiempo. Este proceso realiza la compilacion de todos los
elementos seleccionados en la etapa de configuracion. La compilacion es
un proceso que realiza un uso intensivo del procesador y el tiempo que
tardaremos en compilar el kernel depende exclusivamente de la velocidad
y potencia de nuestro procesador y de la cantidad de memoria del
sistema. Dependiendo de nuestra maquina podemos tardar desde 15 minutos
hasta 1 hora o mas todavia.

  NOTA: Si todavia no le tomaron el gustito a los modulos, prueben de
        olvidarse de compilar algo como parte del kernel y luego tener
        que volver a compilarlo completamente solo para agregar ese
        servicio.

CALCULANDO LAS DEPENDENCIAS

Las fuentes del kernel estan formadas por un gran numero de archivos y
componentes que se encuentran vinculados por relaciones de dependencia.
Estas relaciones de dependencia entre los objetos del kernel deben ser
calculadas de acuerdo a la configuracion del kernel que hayamos
elegido. El siguiente comando calculara las dependencias:

 ==> make dep

LIMPIANDO LO VIEJO

Si no es la primera vez que utilizamos las fuentes del kernel para
compilarlo, debemos tener en cuenta que existen archivos compilados del
kernel anterior y es indispensable eliminarlos antes de comenzar el
proceso de construccion. El siguiente comando se ocupara de limpiar
todos los archivos innecesarios:

 ==> make clean

CONSTRUYENDO EL KERNEL

Para compilar los kernels 2.2.x debemos asegurarnos de tener instalada
la version 2.7.2 del compilador de C/C++ gcc, o alguna mas nueva. Para
averiguar esto podemos ejecutar el siguiente comando:

 ==> gcc --version

 Para construir el kernel debemos ejecutar

 ==> make zImage

Este es proceso que tarda mas tiempo y genera una imagen comprimida del
kernel. Una vez que este proceso termina el kernel se encuentra listo
para ser instalado. En caso de haber seleccionado demasiados servicios
para que sean compilados como parte del kernel, el proceso de
construccion se abortara quejandose de esto. Para contrarrestar esto
podemos probar con el siguiente comando:

 ==> make bzImage

Si el proceso se sigue quejando, entonces debemos eleminar alguno de
los servicios elegidos o seleccionarlos para que se compilen como
modulos, y luego volver a calcular las dependencias, limpiar los
archivos y comenzar de nuevo la construccion.

11.4.3 COMPILANDO LOS MODULOS

Si en la etapa de configuracion seleccionamos algun item para que sea
compilado como modulo, entonces debemos ejecutar el siguiente comando:

 ==> make modules

Este comando realiza la compilacion de los modulos que seleccionamos en
la etapa de configuracion.

11.4.4 INSTALANDO LOS MODULOS

En lo que respecta a los modulos, nos resta instalarlos. Los modulos
son normalmente instalados en el directorio /lib/modules. En este
directorio encontraremos un subdirectorio por cada version kernel para
la que hayamos instalado modulos anteriormente.

Ejecutando el siguiente comando, instalaremos los modulos en ese
directorio bajo el subdirectorio correspondiente a la version del
kernel que estemos ejecutando.

 ==> make modules_install

11.4.5 INSTALANDO EL NUEVO KERNEL

Una vez que tenemos nuestro kernel compilado debemos instalarlo para
que el sistema comience a trabajar con el mismo. La mayoria de los
usuarios de Linux utilizan el programa LILO (LInux LOader) para
instalar el kernel. LILO es un programa facil de utilizar, aunque el
archivo de configuracion /etc/lilo.conf suele confundir un poco a los
usuarios novatos. El archivo de configuracion debe parecerse al que se
muestra en la figura 11.2.

 # cat /etc/lilo.conf
 boot=/dev/hda
 map=/boot/map
 install=/boot/boot.b
 image=/boot/vmlinuz
         label=linux
         root=/dev/hda1
         read-only

        Figura 11.2: Un archivo de configuracion del programa LILO.

 Tres puntos importantes a tener en cuenta:

 1. La linea image=...: Aqui le indicamos a LILO la ruta donde se
                        encuentra la imagen comprimida del kernel.

 2. La linea label=...: Esta opcion le indica al programa que estiqueta
                        usar para ese kernel. La etiqueta es util en
                        caso de tener mas de un S.O. en la misma
                        maquina, ya que LILO nos permite iniciar
                        cualquiera de ellos eligiendo la respectiva
                        etiqueta.

 3. La linea root=...: Con esta opcion le indicamos a LILO cual es la
                       particion raiz de nuestro sistema.

Debemos configurar estas opciones en el archivo de configuraciones,
guardarlo y luego copiar la imagen comprimida del kernel que se
encuentra en el dirctorio /usr/src/linux/arch/i386/boot bajo el nombre
zImage o bzImage, segun hayamos elegido al construirlo, a el lugar que
le fue indicado a LILO en el archivo de configuracion.

Luego debemos ejecutar lilo (o /sbin/lilo si la shell no lo encuentra).
Esto hara que LILO lea el archivo de configuracion e instale el nuevo
kernel bajo las opciones especificadas.

Para poder trabajar con el nuevo kernel, resta reiniciar el sistema. La
instalacion de un nuevo kernel es uno de los unicos motivos por los
cuales es necesario reiniciar el sistema, ya que no nos queda otra
opcion.

En general podremos reiniciar el sistema ejecutando el comando:

 ==> reboot

  o equivalentamente

 ==> init 6

11.4.6 CARGANDO Y DESCARGANDO LOS MODULOS

Una vez que iniciamos el sistema con el nuevo kernel y verificamos que
todo funciona correctamente, podemos comenzar a probar los modulos
seleccionados y compilados anteriormente.

Los comandos referidos a la manipulacion de modulos son los siguientes:

 * lsmod (list modules): Muestra una lista de los modulos cargados
                         actualmente.

 * isnmod (insert module): Carga un modulo en memoria como parte del
 kernel.

 * rmmod (remove module): Elimina un modulo cargado en memoria.

Inicialmente, no se encuentra cargado ningun modulo en memoria. Por lo
tanto, al ejecutar lsmod obtendremos una lista vacia:

 # lsmod
 Module             Size     Used by

En la figura 11.3 se muestra el contenido de los directorios que
contienen los modulos en un sistema.

Ilustraremos la carga y descarga de los modulos con el modulo minix que
nos permite montar sistemas de archivos del S.O. Minix. Veamos que pasa
si queremos montar un diskette con sistema de archivo minix sin tener
el modulo cargado:

 # mount -t minix /dev/fd0 /mnt/floppy
 mount: fs type minix not supported by kernel

El comando mount nos indica que hay un error, ya que el sistema de
archivos Minix no se encuentra soportado por el kernel. Para poder
montar el sistema de archivos de Minix debemos cargar el modulo minix.
Para cargar el mismo ejecutamos el comando insmod y luego verifiamos
que haya sido cargado:

 # insmod minix
 # lsmod
 Module             Size     Used by
 minix             22568      0  (unused)

Una vez que tenemos el modulo caragado como parte del kernel podemos
montar tranquilamente el diskette. Notemos que el modulo esta cargado
pero nadie lo esta utilizando. Veamos como montar el diskette:

 # mount -t minix /dev/fd0 /mnt/floppy lsmod
 Module             Size     Used by
 minix             22568      1

Como vemos, ahora el modulo esta siendo usado por 1 servicio ya que al
montar el diskette el modulo se utiliza hasta que el mismo se desmonte.
Una vez que ya no necesitamos utilizar el diskette lo desmontamos y
luego verificamos que el modulo ya no esta siendo utilizado:

 # rmmod minix
 # lsmod
 Module             Size     Used by

11.4.7 LAS DEPENDENCIAS ENTRE LOS MODULOS

Asi como los distintos componentes que forman parte del kernel poseen
dependencias, los modulos tambien se vinculan por relaciones de
dependencia. En el caso del ejemplo anterior del modulo minix vimos que
el mismo no depende de ningun otro modulo, por lo que podemos cargarlo
directamente y comenzar a utilizarlo. No todos los modulos poseen esta
caracteristica y, como consecuencia, puede no ser tan facil cargarlos.

 # pwd
 /lib/modules/2.2.5
 #ls *
 modules.dep

 block:
 loop.o

 fs:
 minix.o     msdos.o

 misc:
 ad1848.o    af_spx.o    ipx.o    mad16.o    sb.o    uart401.o

 net:
 8390.o      bsd_comp.o    dummy.o    ne.o    ppp_deflate.o

             Figura 11.3: Una serie de modulos instalados

Suponiendo el mismo conjunto de modulos de la figura 11.3 queremos
instalar otro modulo.

Uno de los items que seleccionamos para que sea compilado como modulo
en la etapa de configuracion es el manejador de dispositivo de una
placa de red compatible NE2000. Una vez que examinamos el subdirectorio
net encontramos el modulo ne y lo instalamos con el comando insmod de
la siguiente forma:

 # insmod ne
 /lib/modules/2.2.5/net/ne.o: unresolved symbol ei_open
 /lib/modules/2.2.5/net/ne.o: unresolved symbol ethdev_init
 /lib/modules/2.2.5/net/ne.o: unresolved symbol ei_interrupt
 /lib/modules/2.2.5/net/ne.o: unresolved symbol NS8390_init
 /lib/modules/2.2.5/net/ne.o: unresolved symbol ei_close

¿ Que paso ?

La respuesta es la siguiente: el modulo no puede resolver ciertos
simbolos. Esto quiere decir que depende de algun otro modulo. Por lo
tanto antes de cargar el modulo "ne" debemos cargar los modulos de los
cuales depende. Pero... ¿ cuales son los modulos de los que depende ?.
En este caso, una detallada examinacion de los mensajes de error del
comando insmod pueden hacernos sospechar que el numero 8390 que por ahi
anda dando vueltas implica que el modulo 8390, que se encuentra en el
mismo directorio que ne, es necesario para poder cargarlo. Por lo
tanto, probamos:

 # insmod 8390
 # insmod ne

Efectivamente esto funciono, y lo podemos verificar con el comando
lsmod. En la tabla que nos muestra este comando vemos que el modulo
8390 es utilizado por el modulo ne.

 # lsmod
 Module             Size     Used by
 ne                 5980      1
 8390               5940      0  [ne]

Esta aproximacion, claramente, no es practica. Un modulo puede depender
de varios y podemos tener situaciones donde las dependencias entre
modulos son transitivas, es decir, que un modulo M3 depende de otro
modulo M2 y este, a su vez, depende de otro modulo M1. Asi vemos que
las cosas se complican; si no contamos con una herramienta que realice
automaticamente estas tareas de resolusion de dependencias, la carga y
descarga de modulos se vuelve una tarea bastante complicada.

Por suerte, existen dos utilidades que nos resuelven estos problemas
ideseables.

11.4.8 UNA CARGA MAS INTELIGENTE

El programa depmod es una utilidad que sirve para calcular
automaticamente las dependencias entre los modulos. Puede ser utilizado
de varias formas, pero la mas comun de ellas es la siguiente:

 ==> depmod -a

Este comando ejecutara depmod con la opcion -a (all) y asi calculara
todas las dependencias entre los modulos. Este comando es ejecutado,
usualmente, como parte del inicio del sistema.

Una vez que se calculan las dependencias entre los modulos, podemos
cargar los modulos sin saber que dependencias tienen, ya que el sistema
se ocupara de cargar los modulos necesarios (de acuerdo a las
dependencias) de forma totalmente transparente al usuario. Para poder
realizar la carga de los modulos de esta forma, debemos utilizar el
comando modprobe.

Veamos un ejemplo de esta estrategia:

Queremos cargar el modulo mad16, que sabemos es el manejador de
dispositivo de un tarjeta de sonido. Supongamos que la misma esta
configurada para trabajar en el puerto 0x530, utiliza la interrupcion
(IRQ) 10 y el acceso directo a memoria (DMA) 1. Por supuesto, no
tenemos las mas minima idea de que modulos es necesario cargar para que
mad16 funcione correctamente. No hay problema, ejecutando los
siguientes comandos todo se hara de forma automatica y transparente.

 # lsmod
 Module             Size     Used by
 # depmod -a
 # modprobe mad16 io=0x530 irq=10 dma=1
 # lsmod
 Module             Size     Used by
 mad16              6548      0  (unused)
 uart401            5572      0  [mad16]
 ad1848            15088      0  [mad16]

Como vemos, al comenzar no tenemos ningun modulo cargado. Antes de
cargar el modulo mad16 realizamos el calculo de las relaciones de
dependecia entre los modulos. Luego cargamos el modulo mad16. Notemos
que este modulo (como muchos de los que implementan manejadores de
dispositivos de placas de sonido) necesitan parametros adicionales para
poder ser cargados. En este caso son necesarios el puerto de
entrada/salida, la interrupcion y el acceso directo a memoria que
utiliza la misma. Luego de cargar el modulo, realizamos un listado de
los modulos que se encuentran cargados y descubrimos que el modulo
mad16 posee dos dependencias: uart401 y ad1848. Estos modulos fueron
cargados automaticamente para poder cargar el modulo mad16.

Para descargar el modulo y todas sus dependencias (que no se encuentren
en uso) podamos ejecutar modprobe -r:

 # modprobe -r mad16
 # lsmod
 Module             Size     Used by

11.5 ACTUALIZANDO NUESTRO KERNEL

Una de las grandes ventajas del S.O. Linux es su desarrollo. El kernel
del sistema se encuentra en constante actualizacion y desarrollo, a tal
punto que podemos disponer de una nueva version del mismo cada, mas o
menos, una o dos semanas. Comparemos esto con la frecuencia de
actualizacion de otros S.O., si es que tiene actualizacion :)

Es importante actualizar nuestro kernel ya que a medida que los kernels
evolucionan se corrigen muchos "bugs", son capaces de trabajar con
nuevos dispositivos, se agrega soporte para otros sistemas de archivos,
pueden mejorar el manejo de puntos claves (memoria, procesos, etc.),
pueden ser mas rapidos y mas estables, etc.

11.5.1 OBTENIENDO EL KERNEL

Existen varias formas de obtener las fuentes del kernel. Una de ellas
es mediante Internet ya que existen varios sitios donde se publican las
mismas. Ver al apendice A para obtener las direcciones de los sitios.
Existen, tambien varias distribuciones en CD-ROM's que traen las
fuentes de los kernels.

Un punto importante a tener en cuenta al momento de conseguir las
fuentes del kernel es la version de las mismas.

VERSIONES DEL KERNEL

Las fuentes del kernel poseen un sistema de numeracion muy simple.
Cualquier version par de las fuentes representa un kernel estable, por
ejemplo 2.0 o 2.2. Una version impar representa un kernel en estado
experimental o en desarrollo (las famosas versiones "beta"), por
ejemplo 2.1.

A su vez sobre cada version se publican varios "releases", es decir
subversiones de los mismos. Asi podemos tener versiones como 2.0.32,
2.1.125, 2.2.5, etc. En general, existen un gran numero de releases
betas antes de publicar la siguiente version estable. Por ejemplo,
antes de que se publicara la version 2.2 del kernel se realizaron mas
de 130 releases del kernel 2.1. Podemos ver el grado de testeo y
correccion de los kernels antes de ser denominados "estables" y por lo
tanto ser considerados confiables y aceptables. La politica de los
desarrolladores de Linux es testear intensivamente los kernels antes de
publicar una nueva version estable, por lo que podemos estar seguros de
que si la version es par es "realmente estable". Comparemos esto con
las estrategias de desarrollo de otros S.O.

11.5.2 INSTALANDO LAS FUENTES DEL KERNEL

Las fuentes del kernel son provistas en un archivo agrupado y
comprimido con el formato tar y gzip o alternativamente bzip2. Si la
version es, digamos, 2.2.1, entonces el archivo se llamara
linux-2.2.1.tar.gz o linux-2.2.1.tar.bz2. Estas fuentes deben ser
instaladas dentro del directorio /usr/src.

Como es posible que tengamos en ese mismo diretorio las fuentes de
kernels de versiones anteriores, es recomendable realizar un par de
cosas antes de descomprimir las nuevas fuentes. Supongamos que dentro
del directorio /usr/src tenemos instaladas las fuentes del kernel
2.1.125 y queremos instalar las fuentes del nuevo kernel 2.2.5. El
contenido del directorio /usr/src es el siguiente:

 # pwd
 /usr/src
 # ls -l
 lrwxrwxrwx    1 root     root        11 May 5 23:58 linux -> linux-2.1.125
 drwxr-xr-x   15 root     root      1024 May 5 23:50 linux-2.1.125
 -rw-r--r--    1 root     root  13721493 May 9 22:17 linux-2.2.5.tar.gz

Las fuentes del kernel actuales deben encontrarse en el directorio
linux. Es conveniente que se realice un directorio para cada version de
las fuentes y crear un link simbolico linux que apunte al directorio
respectivo. En este caso el link apunta al directorio linux-2.1.125 ya
que es la unica version que tenemos.

Si descomprimimos las nuevas fuentes en este momento tendremos un
problema: En general, estos archivos comprimidos viene armados para que
al descomprimirlos se instalen en el directorio linux, pero como
nosotros tenemos el link simbolico apuntando al directorio
linux-2.1.125, al descomprimir las fuentes, estas se instalaran en este
ultimo directorio y sobrescribiran las fuentes del kernel 2.1.125. Para
evitar esto, debemos eliminar el link simbolico antes de descomprimir
las nuevas fuentes. En la figura 11.4 vemos como hacer para instalar
correctamente las fuentes del kernel y conservar las anteriores.

 # rm linux
 # ls -l
 drwxr-xr-x  15 root    root      1024 May 5 23:50 linux-2.1.125
 -rw-r--r--   1 root    root  13721493 May 9 22:17 linux-2.2.5.tar.gz
 # tar -zxvf linux-2.2.5.tar.gz
 # ls -l
 drwxr-xr-x  15 root    root      1024 May 9 22:30 linux-2.1.125
 drwxr-xr-x  15 root    root      1024 May 5 23:50 linux-2.2.5
 -rw-r--r--   1 root    root  13721493 May 9 22:17 linux-2.2.5.tar.gz
 # mv linux linux-2.2.5
 # ls -l
 drwxr-xr-x  15 root    root      1024 May 5 23:50 linux-2.1.125
 drwxr-xr-x  15 root    root      1024 May 9 22:32 linux-2.2.5
 -rw-r--r--   1 root    root  13721493 May 9 22:17 linux-2.2.5.tar.gz
 # ln -s linux-2.2.5 linux
 # ls -l
 lrwxrwxrwx   1 root    root         9 May 9 23:33 linux -> linux-2.2.5
 drwxr-xr-x  15 root    root      1024 May 5 23:50 linux-2.1.125
 drwxr-xr-x  15 root    root      1024 May 9 22:32 linux-2.2.5
 -rw-r--r--   1 root    root  13721493 May 9 22:17 linux-2.2.5.tar.gz

      Figura 11.4: Descomprimiendo las fuentes del nuevo kernel.

Para completar la instalacion del nuevo kernel debemos realizar un paso
adicional para asegurarnos de que no tenemos ningun vinculo incorrecto.
Debemos cambiar el directorio /usr/src/linux y ejecutar el siguiente
comando:

 ==> make mrproper

Ahora si tenemos las fuentes del kernel correctamente instaladas.


CAPITULO 12

ASPECTOS AVANZADOS DE LA SHELL

Ya hemos discutido la utilizacion de la shell en el capitulo 6 y la
hemos utilizado interactivamente de manera intensiva. Los usuarios
utilizan la shell, en su gran mayoria, interactivamente de las
siguientes formas:

 * Ingresando comandos simples (ls).

 * Utilizando las facilidades de generacion de nombres de archivos (ls
   *.tex).

 * Especificando redireccion de la entrada y/o salida (ls > iofile).

 * Construyendo cañerias (ls | wc -l).

Estas tecnicas son potentes y extremadamente utiles, pero solo son una
pequeña parte de las capacidades de la shell.

Elegir una shell interactiva es en realidad una cuestion de gusto.
Muchos usuarios prefieren la shell "C" para uso interactivo. La misma
fue la primera shell que implemento una lista historica de los comandos
para poder ser reutilizados facilmente sin tener que tipearlos
nuevamente. Tambien fue la primer shell que implemeto el control de
procesos, es decir, como poder manipular procesos que se ejecutan en
background. Elegir una shell para escribir un scripts es una tarea
mucho mas facil. Si las necesidades del usuario son modestas y se
conocen las capacidades de la shell de "C", entonces es conveniente
utilizarla, pero la mayoria de los usuarios, hoy, prefieren utilizar la
shell de "Bourne" para escribir scripts.

La shell de "Bourne" (sh) es la unica shell que se encuentra en todos
los sistemas Unix, incluido Linux, que ademas posee la shell "Bourne
Again" (bash) que es totalmente compatible con la shell de Bourne y
agrega caracteristicas importantes y utiles de la shell de "Korn" (ksh)
y la shell de "C" (csh). La shell de Bourne Again es la shell
predeterminada de Linux.

La shell de "Bourne" fue diseñada desde un comienzo como un lenguaje de
programacion, lo que explica las capacidades de la misma como lenguaje
de programacion lo que la hace la shell mas ampliamente aceptada como
lenguaje de programacion de scripts.

Este capitulo no intenta desarrollar completamente las capacidades de
la shell de Bourne como lenguaje de programacion, sino que pretende ser
una introduccion a la programacion de scripts, tarea no indispensable
para un usuario ordinario, pero que puede hacer que muchas de las
tareas a realizar en el sistema sean mas faciles y practicas.
Analizaremos tambien los aspectos de la shell que forman el entorno del
usuario, como lo son: variables de entorno, variables de shell, el
camino de busqueda (path), etc.

12.1 PROGRAMAS DE SHELL (SRIPTS)

Un script es cualquier comando o secuencia de comandos de Linux
almacenados en un archivo de texto. Usualmente el termino de script se
utiliza cuando el archivo solo contiene una simple secuencia de
comandos; el termino programa de shell identifica un archivo que
contiene una estructura de comandos mas compleja.

Un usuario puede ejecutar un programa de shell o un script directamente
ingresando el nombre del archivo en la linea de comandos. Los programas
de la shell se tratan de la misma forma que cualquier otro ejecutable.
Por supuesto, debemos tener permiso de ejecucion sobre el archivo que
contiene el script y ademas la shell debe poder encontrar el archivo
dentro del camino de busqueda (path).

12.2 VARIABLES DE LA SHELL

Como en cualquier lenguaje de programacion, las variables de la shell
se utilizan para almacenar valores para luego poder ser utilizados. El
termino variable sugiere que el valor de la misma puede cambiar durante
el flujo de ejecucion.

Las variables de la shell solo pueden guardar cadenas de texto
(strings). Los numeros, en las variables de la shell, son almacenados
como cadenas de caracteres.

Para asignar valores a las variables utilizamos el comando de
asignacion (=). El valor almacenado en una variable se denota como
$var, donde var es la variable en cuestion. Siempre que usemos el
nombre de la variable, este denotara el nombre de la variable y no su
valor, a diferencia de la mayoria de los lenguajes de programacion.
Veamos un ejemplo de esto en la figura 12.1.

 # Boca = campeon
 bash: Boca: command not found
 # River=campeon
 # echo River
 River
 # echo $River
 campeon
 # echo $Boca

 # River=Capo
 # echo $River
 Capo

       Figura 12.1: Seteando y consultando variables de la shell.

En esta figura vemos varias cosas interesantes ( Je, je ademas de que
la shell no conoce a Boca y si a River :):

 * Debemos ser cuidadosos al utilizar el comando de asignacion, ya que
   la shell nos obliga a ponerlo inmediatamente depues del nombre de la
   variable, ya que sino la primer palabra es interpretada como un
   comando y, cuando la shell intenta ejecutarlo no lo encuentra.

 * El comando echo visualiza una linea de texto en la salida estandar.
   Cuando ejecutamos el primer comando echo, vemos que la linea de
   texto ingresada ("River") es visualizada en pantalla. Cuando
   utilizamos el simbolo $ antes del nombre de la variable River, la
   shell reemplaza $River por el valor de la variable, es decir la
   cadena "campeon". Esta cadena es la que es pasada como argumento al
   comando y el mismo la visualiza en pantalla.

 * Es muy importante comprender que la manipulacion de las vatiables y
   sus valores la realiza la shell y no el comando echo.

 * Una variable pierde su valor anterior si es asignada de nuevo.

 * Una variable que no ha sido asignada tiene la cadena nula o vacia.

Cuando queremos asignar a una variable una cadena de caracteres que
contiene espacios debemos encerrar toda la cadena entre comillas. Vemos
un ejemplo en la figura 12.2.

 # Boca=No existe
 bash: existe: command not found
 # Boca="No existe"
 # echo $Boca
 No existe
 #

   Figura 12.2: Utilizando comillas para asignar cadenas a las
   variables.

12.2.1 EXPORTANDO VARIABLES DE LA SHELL

Las variables de la shell que creamos son locales a la shell activa a
no ser que sean exportadas explicitamente. El comando export nos sirve
para exportar variables. Con el siguiente comando podemos exportar la
variable var:

 ==> export var

Si ejecutamos export sin argumentos obtendremos una lista de las
variables exportadas.

Este comando solo lista las variables exportadas de la shell actual.

Una variable exportada permanece en ese estado hasta que la shell en la
que fue marcada para exportacion sea terminada.

12.2.2 VARIABLES AUTOMATICAS DE LA SHELL

Las siguientes variables son seteadas automaticamente por la shell:

 $? Contiene el valor de salida retornado por el ultimo comando
 ejecutado.

 $$ Contiene el PID de la shell actual.

 $! Contiene el PID del ultimo proceso que se invoco en background.

 $# Contiene el numero de parametros que fueron pasados a la shell.

 $* Contiene la lista de argumentos actual.

Estas variables pueden ser utilizadas como todas las demas. Por ejemplo
podemos utilizar la variable $$ para ver el numero de proceso de la
shell actual.

 # ps
   PID TTY STAT  TIME COMMAND
   443   1 S    0:00 /bin/login -- tony
   451   1 S    0:00 -bash
   462   1 S    0:00 sh /usr/X11R6/bin/startx
   463   1 S    0:00 xinit /home/tony/.xinitrc --
   467   1 S    0:02 wmaker
   490   1 S    0:57 emacs -fn 9x15
   541  p7 S    0:00 /bin/bash
   594  p7 R    0:00 ps
 # echo $$
 541

12.2.3 VARIABLES ESTANDAR DE LA SHELL

El significado de una gran cantidad de variables ha sido estandarizado
con el paso del tiempo. Esta variables son como todas las demas, pero
tiene un significado convencional que debemos entender. Estas variables
son llamdas usualmente variables de entorno.

Podemos producir un listado de las variables actualmente asignadas con
el comando set.

Veamos un listado de ejemplo en la figura 12.3.

 # set
 BASH=/bin/bash
 BASH_VERSION=1.14.7(1)
 COLUMNS=104
 DISPLAY=:0
 ENV=/home/tony/.bashrc
 EUID=500
 HISTFILE=/home/tony/.bash_history
 HISTFILESIZE=1000
 HISTSIZE=1000
 HOME=/home/tony
 HOSTNAME=tonyx
 HOSTTYPE=i386
 IFS=

 LD_LIBRARY_PATH=/usr/local/qt/lib
 LINES=24
 LOGNAME=tony
 MAIL=/var/spool/mail/tony
 MAILCHECK=60
 MANPATH=/usr/local/qt/man:/usr/man:/usr/local/man
 OLDPWD=/home/tony/docs/linux
 OSTYPE=Linux
 PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:.
 PPID=490
 PS1=#
 PS2=>
 PS4=+
 PWD=/home/tony/docs/linux
 SHELL=/bin/bash
 TERM=dumb
 UID=500
 USER=tony
 USERNAME=tony

             Figura 12.3: Listado de variables de entorno.

La mayoria de estas variables se crean durante el proceso de inicio de
sesion (login) y son una parte muy importante de la funcionalidad del
sistema. Algunas de las variables que forman parte de la lista de la
figura 12.3 son utilizadas por uno o dos programas particulares y no
son de interes general. Vamos a detallar el significdo de las variables
que tienen una importancia vital para nuestro dialogo con Linux y para
que el trabajo de los programas y utilidades se desarrolle
exitosamente.

 $HOME Contiene el nombre del directorio home del usuario. Se setea al
        iniciarse la sesion y es utilizada por los programas que
        necesitan acceder a archivos almacenados en nuestra parte del
        sistema de archivos, por ejemplo, los programas que lee o
        escriben los archivos de configuracion e inicializacion
        llamados dot files, ya que comienzan con un punto y son ocultos
        (.Xdefaults .bash.profile .xinitrc, etc.).

 $PATH Contiene la cadena de busqueda que la shell utiliza cuando busca
        los comandos a ejecutar.

 $IFS Contiene los separadores internos entre campos (Internal Field
       Separators), que son usualmente espacios, tabulador y nueva
       linea. Los separadores de campos separan las palabras de los
       comandos. La linea en blanco que se encuentra despues de IFS es
       parte del valor de la variable.


 $LOGNAME $USER $USERNAME Es el nombre de usuario (login). Se usan
                           alternativamente.

 $MAIL o $MAILPATH Se utilizan si queremos ser notificados de la
                    llegada de nuevo correo electronico.

 $MAILCHECK Es el intervalo, en segundos, entre chequeos de nuevo mail.

 $SHELL Es el nombre de la shell de inicio. Es utilizada por programas
         que invocan a shells interactivas para utilizar sin necesidad
         de salir del programa. Un ejemplo es emacs.

 $PS1 Es la cadena que la shell utiliza como prompt primario.

 $PS2 Es la cadena utilizada como prompt secundario. Es utilizado
       cuando la shell detecta que los comandos estan obviamente
       incompletos y nos piden informacion adicional. Usualmente es un
       simbolo >.

 $TERM Contiene el modelo de terminal utilizado. Algunos comandos
        necesitan conocer el tipo de terminal para poder generar una
        salida correcta.

12.3 EL CAMINO DE BUSQUEDA (PATH)

Cuando ingresamos un comando, la primera cosa que la shell hace es
buscar el programa asociado. Pero, ¿Donde es que lo busca? Muchas
instalaciones de Linux contiene cientos de directorios y consumiria
mucho tiempo buscar en todos los directorios. Para concentrar la
busqueda, la shell del sistema mantiene un camino de busqueda (PATH),
tambien conocida como cadena de busqueda.

El PATH es una lista de directorios donde la shell busca los comandos
ingresados. Los PATH's en general contiene en directorio /bin, el
directorio /usr/bin, etc., ya que en estos directorios es donde se
encuentran los comandos y utilidades estandar.

El PATH puede ser modificado para que la shell busque en directorios
adicionales, cuando ingresamos algun comando. Si la shell no encuentra
en ninguno de los directorios el comando especificado, entonces muestra
un mensaje diciendonos que no lo pudo localizar. Podemos consultar cual
es la lista de directorios que forman parte del path ejecutando:

 ==> echo $PATH

Historicamente, se trataba de mantener los PATH's con una longuitud
pequeña, ya que forzaban a la shell a invertir mucho tiempo en las
busquedas, lo que terminaba resistiendo el tiempo de respuesta de la
shell. Hoy, tanto la shell de Bourne como la shell de C, operan de una
forma mas eficiente, manteniendo un "cache" de los comandos, es decir
que recuerda donde se encuentran los comandos y por lo tanto solo
realizan una sola vez la busqueda, no importa la cantidad de veces que
utilicemos el comando. Similarmente es recomendable mantener un tamaño
aceptable en los directorios donde almacenamos los ejecutables. Nos
lleva mucho menos tiempo realizar una busqueda en un directorio que
contiene solo unos pocos archivos que en un directorio que contiene
cientos de archivos.

En algunos sistemas Unix, incluyendo a Linux, el PATH no contiene al
directorio actual. Los usuarios acostumbrados a trabajar con MS-DOS se
sentirar desorientados cuando la shell les muestre un mensaje de error
diciendoles que no encontro un comando que se encuentra en el
directorio actual (suponiendo que el directorio actual no forma parte
del PATH). Para este problema tenemos dos soluciones:

 1. Ejecutar cada comando del directorio actual con el agregado del
    "./". Vemos un ejemplo en la figura 12.4.

     # ls -l
     total 1
     -rwxr-xr-x   1 tony   users           20 Jun  5 21:19 script1
     # cat script1
     echo Hola $USERNAME
     # script1
     bash: script1: command not found
     # ./script1
     Hola tony

     Figura 12.4: Ejecutando un comando que se encuentra en el
                  directorio actual.

 2. Agregar el directorio "." a nuestro PATH. Asi no importa en que
    directorio estemos, siempre se incluira el mismo como parte del
    PATH y la shell encontrara los comandos.

12.4 CARACTERES ESPECIALES - "QUOTING"

Desafortunadamente, muchos de los caracteres especiales utilizados por
la shell (¡, ?, -, etc.) son utilizados por otros programas. El
problema es que no hay tantos simbolos disponibles y siempre pueden
aparecer conflictos. Cuando ejecutamos comandos interactivamente o
cuando ejecutamos un script, la shell es el primer programa que recibe
el texto respectivo. Si el texto de el/los comandos contiene caracteres
especiales, estos seran interpretados por la shell, realizando, la
misma, las modificaciones necesarias. Para que la shell no interprete
estos caracteres especiales, debemos utilizar secuencias de escape. Al
proceso de utilizar secuencias de escape se lo conoce como quoting.

Cuando queremos enviar simbolos especiales a los programas, debemos
utilizar secuencias de escape. Existen tres formas de especificar
secuencias de escapes:

 1. Una barra invertida (\) sirve de escape para los caracteres que la
    siguen inmediatamente.

 2. Todos los caracteres encerrados entre comillas simples (') se
    encuentran bajo una secuencia de escape.

 3. Las comillas dobles (") sirven de escape para todos los caracteres
    que se encuentren entre un par de ellas, salvo los siguientes
    caracteres:

     $ \

Veamos varios ejemplos en la figura 12.5.

 # echo $USER
 tony
 # echo '$USER'
 $USER
 # echo \$USER
 $USER
 # echo "$HOME"
 /home/tony
 # echo "ls | wc -l"
 ls | wc -l

       Figura 12.5: Ejemplos de la utilizacion de caracteres y
                    secuencias de escape.

12.5 ESTADO DE SALIDA DE LOS COMANDOS

Cada comando que ejecutamos retorna un codigo que representa el estado
de salida del comando. Cuando un comando se ejecuta exitosamente,
retorna un codigo de salida que es cero (zero exit status). Por
convencion, si un programa encuentra problemas serios en su ejecucion,
retorna un codigo de estado de salida que es distinto de cero (non-zero
exit status).

Ejemplo: Si ingresamos el siguiente comando:

 ==> ls -l /dev/hda

El comando retornara un codigo igual a 0, ya que el archivo que
representa al primer disco rigido de la maquina existe. Sin embargo, si
ingresamos el comando:

 ==> ls -l /dev/hdz

El comando retornara un codigo distinto de 0, ya que el archivo de
dispositivo especificado no existe y el comando ls encontrara el error.

La variable de entorno $? contiene el codigo de estado de salida del
ultimo comando ejecutado y podemos consultarla en caso de querer
averiguar el codigo de estado de salida de los comandos. Vemos un
ejemplo de esto en la figura 12.6.

 # ls -l /dev/hda
 brw-rw----   1 root     disk     3,    0 Sep  7  1994 /dev/hda
 # echo $?
 0
 # ls -l /dev/hdz
 ls: /dev/hdz: No such file or directory
 # echo $?
 1

         Figura 12.6: Consultando el estado de salida de los comandos.

12.6 LOS ARGUMENTOS

En los programas de la shell, los argumentos de linea de comandos se
encuentran disponibles en una serie de variables numeradas. $1 es la
variable que contiene el primer argumento, $2 contiene el segundo
argumento, y asi siguiendo. Estas variables representan parametros
posicionales.

Existen dos variables especiales que representan informacion adicional
acerca de los argumentos:

 * $0 Representa el valor del argumento 0 que siempre es el nombre del
       programa ejecutado.

 * $# Contiene el numero de parametros ingresados en la linea de
       comandos.

El programa que muestra la figura 12.7 toma como entrada 4 argumentos y
como salida retorna los 4 argumentos en orden invertido. El programa
fue realizado utilizando estas variables que representan los
argumentos.

 # cat reverse
 if [ $# -eq 4 ]
 then
        echo $4 $3 $2 $1
 else
        echo Uso: $0 arg1 arg2 arg3 arg4
 fi
 # reverse
 Uso: $0 arg1 arg2 arg3 arg4
 # revese 12 34 56 78
 78 56 34 12
 #

     Figura 12.7: Un programa que utiliza las variables de argumentos.

12.7 ESTRUCTURAS DE CONTROL

Como cualquier otro lenguaje de programacion, el lenguaje de
programacion de la shell nos brinda la posiblidad de utilizar
estructuras de control. En el ejemplo de la figura 12.7, vimos de forma
adelantada, el condicional if.

A continuacion veremos un resumen de las estructuras de control que
provee el lenguaje de programacion de la shell.

12.7.1 CONDICIONALES SIMPLES

Los condicionales simples son operadores que nos permiten tomar
decisiones entre las ejecuciones de los distintos comandos.

El condicional mas simple es el operador &&. Cuando dos comandos son
separados por este operador, el segundo comando se ejecutaro solo si el
primero retorna un codigo de estado de salida igual a 0 (indicando una
ejecucion exitosa).

Este operador es util para indicarle a la shell que queremos ejecutar
una secuencia de comandos, pero solo si se van ejecutando exitosamente.
En caso de que alguno falle, los demas no se ejecutaran.

En el capitulo 9 vimos que para compilar e instalar un programa debemos
ejecutar una secuencia de comandos. Podemos automatizar estos procesos
ejecutando los comandos de la siguiente forma:

 ==> ./configure && make && make install

De esta forma, solo se construira el programa (make) si la
configuracion (./configure) fue exitosa y solo se instalara (make
install) si se construyo correctamente.

El operador opuesto a && es ||.

Cuando dos comandos son separados por || el segundo comando se
ejecutara solo si el primero finaliza retornando un codigo de salida
distinto de 0.

12.7.2 EL CONDICIONAL IF

Los operadores && y || son utiles para crear sentencias condicionales
muy simples. La shell tiene estructuras condicionales mas sofisticadas
como puede ser el condicional if.

La sintaxis de esta estructura es:

  if "listas de condiciones"
  then
      "listas de comandos"

  elif "listas de condiciones"

      "listas de comandos"
  else
       "listas de comandos"
  fi

12.7.3 LOS LOOPS CONDICIONALES WHILE Y UNTIL

Los loops condicionales nos permiten repetir un grupo de comandos.

La sintaxis del condicional while es la siguiente:

 while "lista de condiciones"
      do "lista de comandos"
 done

La sintaxis de until es la siguiente:

 until "lista de condiciones"
      do "lista de comandos"
 done

12.7.4 LA SENTENCIA FOR

La sentencia for nos permite ejecutar una lista de comandos
repetidamente. Esta sentencia nos exige que le ingresemos uns lista de
palabras y ejecuta la lista de comandos una vez para cada palabra. La
forma general de la sentencia es la siguiente:

 for "nombre" in "palabra1" "palabra2" ...
 do
   "lista de comandos"
 done

La sentencia for puede ser utilizada sin la palabra "in". De esta forma
la lista de palabras automaticamente sera la lista de parametros
posicionales. Vemos un ejemplo en la figura 12.8.

 # ls
 comandos    environ*     existe*    reverse*   rxvt-linux*
 # cat existe
 for archivo
 do
   if test -r $archivo
   then
      echo $archivo existe !!!
   else
      echo $archivo no existe !!!
   fi
 done
 # existe reverse comandos windows
 reverse existe !!!
 comandos existe !!!
 windows no existe !!!

   Figura 12.8: Utilizando la sentencia for con parametros posicionales.

12.7.5 LA SENTENCIA CASE

La sentencia case de la shell es una forma de elegir varios caminos de
ejecucion basandose en una comparacion por pattern matching.

Su forma general es la siguiente:

 case "word" in
     "pattern1") "lista de comandos" ;;
     "pattern2") "lista de comandos" ;;
     ...
 esac

12.8 EVALUACION DE CONDICIONES - TEST

El comando test es utilizado en los scripts para testear ciertas
condiciones y determinar, por ejemplo, si los archivos o directorios
existen, etc. Este comando, que viene integrado con la shell, puede ser
utilizado para realizar tres tipos de tests:

 1. Puede testear los archivos para averiguar ciertas caracteristicas.

 2. Puede realizar comparaciones entre cadenas.

 3. Puede realizar comparaciones numericas.

El comando indica el exito o el fracaso del test utilizando su codigo
de estado de salida. La utilizacion de los crchetes es un sinonimo del
comando test. Veamos un ejemplo de la utilizacion de test en la figura
12.9.

 # pwd
 /home/tony/linux
 # echo $HOME
 /home/tony
 # [ $HOME = 'pwd' ] || echo No estamos en casa ;(
 No estamos en casa ;(
 # cd ..
 # [ $HOME = 'pwd' ] || echo No estamos en casa ;(
 #

          Figura 12.9: Evaluando condiciones con tets.

El set completo de opciones del comando test se muestra en la tabla 12.1.

 -------------------------------------------------------------------------
                              Test de archivos

 -b archivo                 Verdadero si el archivo existe y es un archivo
                            de dispositivo de bloque.
 -c archivo                 Verdadero si el archivo existe y es un archivo
                            de dispositivo de caracter.
 -d archivo                 Verdadero si el archivo existe y si es un
                            directorio.
 -e                         Verdadero si el archivo existe.
 -f                         Verdadero si el archivo existe y es un archivo
                            ordinario.
 -L archivo                 Verdadero si el archivo existe y es un link
                            simbolico.
 -r archivo                 Verdadero si el archivo existe y es posible
                            leerlo.
 -s archivo                 Verdadero si el archivo existe y su longuitud
                            es nayor a cero.
 -w archivo                 Verdadero si el archivo existe y es posible
                            escribirlo.
 -x archivo                 Verdadero si el archivo existe y es ejecutable.
 archivo1 -nt archivo2      Verdadero si el archivo 1 es mas nuevo que el
                            archivo 2.
 archivo1 -ot archivo2      Verdadero si el archivo 1 es mas viejo que el
                            archivo 2.
 -------------------------------------------------------------------------
                         Comparaciones de cadenas

 -z string                  Verdadero si la longuitud de la cadena es 0.
 string                     Verdadero si la longuitud de la cadenas es
                            mayor a 0.
 string1 = string2          Verdadero si las dos cadenas son iguales.
 string1 != string2         Verdadero si las dos cadenas son distintas.
 ------------------------------------------------------------------------
                         Comaparaciones numericas

 -eq                        Igualdad (equal)
 -ne                        Distintos (not equal)
 -gt                        Mayor que (greater than)
 -lt                        Menor que (less than)
 -ge                        Mayor o igual que (greater or equal)
 -le                        Menor o igual que (less or equal)
 ------------------------------------------------------------------------
                           Operaciones logicas

 !                         Not (no)
 -a                        And (y)
 -o                        Or (o)
 ------------------------------------------------------------------------

                 Tabla 12.1: Opciones del comando test.

12.9 EVALUACION DE EXPRESIONES - EXPR

El comando expr es un programa simple que realiza operaciones
aritmeticas sobre enteros. La expresion a evaluar se provee en la linea
de comandos y expr produce la salida en la salida estandar.

Cada argumento de este comando deber ser un numero entero o un
operador. Como la mayoria de los argumentos son simbolos utilizados por
la shell, es necesario utilizar secuencias de escape.

Vemos ejemplos simples de la utilizacion de expr en la figura 12.10.

 # expr 2 + 4
 6
 # expr 2 * 6
 expr: syntax error
 # expr 2 \* 6
 12
 # expr 4 / 2
 2
 # expr 5 - 4
 1

         Figura 12.10: Utilizando expr para evaluar expresiones.


****************************************************************

PARTE III


 Contenido

  Introduccion (lo esta leyendo)

  13. Booteo, inicializacion y detencion del sistema
     13.1 MBR, particiones y cargadores
     13.2 Booteo
     13.3 Proceso tradicional de booteo
          13.3.1 Niveles de ejecucion (runlevels)
          13.3.2 init tiene la posta
          13.3.3 Inicializacion del sistema
          13.3.4 Inicio de procesos respectivos al runlevel
          13.3.5 Inicio de los procesos de incializacion de terminales
     13.4 Carga del perfil estandar
     13.5 Carga de los perfiles personalizados
     13.6 Detencion del sistema
  14. Instalacion y configuracion de dispositivos
     14.1 Modems
          14.1.1 Puertos serie y modems
          14.1.2 Modems externos
          14.1.3 Modems internos
          14.1.4 El archivo /dev/modem
          14.1.5 Probando el modem
     14.2 Impresoras
          14.2.1 El dispositivo parport
          14.2.2 Impresoras soportadas
          14.2.3 Configuracion de lp
          14.2.4 Sofware de spooling
     14.3 Tarjetas de sonido
          14.3.1 Instalando la tarjeta de sonido
          14.3.2 Configurando el kernel
          14.3.3 Bootenado Linux y testeando la instalacion
  15. Administracion del sistema
     15.1 Responsabilidades del administrador
     15.2 El superusuario
          15.2.1 El comando su
     15.3 Administracion de cuentas de usuario
          15.3.1 El comando adduser
          15.3.2 Los grupos de usuarios
          15.3.3 Directorios "home"
     15.4 Chequeo de los sistemas de archivos
          15.4.1 El comando fsck
     15.5 Los modos setuid y setgid
     15.6 Ejecucion de programas en intervalos determinados
  16. El sistema de ventanas X Window
     16.1 Requerimientos de hardware
     16.2 Configurando el XFree86
          16.2.1 Seleccionando la tarjeta de video
          16.2.2 Seleccionando el monitor
          16.2.3 Seleccionando la memoria de la tarjeta de video
          16.2.4 Seleccionando el "clocking"
          16.2.5 Seleccionando los modos graficos
          16.2.6 Resolucion virtual
     16.3 Ejecutando XFree86
          16.3.1 El prograna xinit
          16.3.2 El archivo .xinitrc
     16.4 El "Window Manager"
          16.4.1 FVWM/FVWM2/FVWM95
          16.4.2 KDE
          16.4.3 Window Maker
     16.5 Iniciando el sistema en runlevel 5
          16.5.1 El programa xdm
          16.5.2 El archivo .xsession
     16.6 Aplicaciones utiles para el sistema de ventanas X Window

  A. Direcciones relacionadas con el sistema operativo Linux

  Despedida


CAPITULO 13

BOOTEO, INICIALIZACION Y DETENCION DEL SISTEMA

Desde el momento en que prendemos la maquina hasta que aparece el
mensaje de login, una gran serie de procesos se llevan a cabo. Es
importante conocer que cosas se llevan a cabo como parte del proceso de
booteo para modificar el comportamiento del sistema o para corregir el
mismo si no inicia de la forma que deberia.

Hay muchas maneras de modificar el comportamiento del sistema en el
proceso de booteo.

13.1 MBR, PARTICIONES Y CARGADORES

Cuando booteamos desde un disco rigido, el primer sector del disco
(llamado Master Boot Record) es cargado. Este sector contiene un
programa cargador y la tabla de particiones del disco. El programa
cargador usualmente carga el sector de booteo de la particion activa.
EL secto de booteo de la particion contiene otro pequeño cargador que
lee la primera parte del S.O. y lo inicia.

El cargador en el caso de Linux suele ser LILO (LInux LOader) y es el
que carga la primera parte del S.O. Luego es cargado el kernel.

13.2 BOOTEO

Bootear un sistema Linux incluye etapas de diagnostico de hardware,
carga del kernel en memoria, chequeo y montaje de sistema de archivos,
inicio de tareas en background y daemons y establecer el funcionamiento
de la red, entre otras cosas.

El cargador se ocupa de cargar el kernel en memoria. La imagen del
kernel se encuentra comprimida, por lo que contiene un pequeño sector
de codigo al principio de que le indica como descomprimirse
automaticamente. Cuando se termina de descomprimir el kernel el mismo
se carga en memoria.

La imagen del kernel se ubica en el direcorio /boot y el nombre
predeterminado es vmlinuz. Esta imagen es el resultado de la
compilacion del kernel, como vimos en el capitulo 11.

Una vez cargado el kernel en memoria, Linux se encuentra activo y
funcionando. En este momento el S.O. (Sistema Operativo, por si se
olvidaron) comienza a cargar drivers de dispositivos y a establecer la
configuracion del hardware que va detectando. A medida que se instalan
los drivers y se configuran dispositivos el kernel nos va mostrando
mensajes que nos informan que es lo que esta realizando. Estos mensajes
los podemos analizar mas tarde cuando el sistema esta iniciado ya que
se van almacenando en el archivo /var/log/dmesg.

Los mensajes varian dependiendo de los diferentes sistemas, del
hardware que se posea, de la version del kernel, y de como se encuentra
configurada.

Los mensajes que el kernel muestra pueden ser observados en la figura
13.1. Las lineas fueron numeradas para utilizarlas como referencia mas
adelante.

 [01] Linux version 2.2.5 Tue May 11 20:15:59 ART 1999
 [02] Detected 350809121 Hz processor.
 [03] Console: colour VGA+ 80x25
 [04] Calibrating delay loop... 699.60 BogoMIPS
 [05] Memory: 95648k/98304k available
 [06] CPU: AMD AMD-K6(tm) 3D processor stepping 0c
 [07] Checking 386/387 coupling... OK, FPU using exception 16 error reporting.
 [08] Checking 'hlt' intruction... OK.
 [09] POSIX conformance testing by UNIFIX
 [10] PCI: PCI BIOS revision 2.10 entry at 0xfb490
 [11] PCI: Using configuration type 1
 [12] PCI: Probing PCI hardware
 [13] Linux NET4.0 for linux 2.2
 [14] NET4: Unix domain sockets 1.0 for linux NET4.0.
 [15] NET4: Linux TCP/IP 1.0 for NET4.0
 [16] IP Protocols: ICMP, UDP, TCP
 [17] parport0: PC-style at 0x3bc [SPP,PS2]
 [18] Detected PS/2 Mouse Port.
 [19] Serial driver version 4.27 with no serial options enabled
 [20] ttyS00 at 0x03f8 (irq = 4) is a 16550A
 [21] ttyS01 at 0x02f8 (irq = 3) is a 16550A
 [22] lp0: using parport0 (polling).
 [23] apm: BIOS version 1.2 Flags 0x07 (Diver version 1.9)
 [24] VP_IDE: IDE controller on PCI bus 00 dev 39
 [25]    ide0: BM-DMA at 0xe000-0xe007, BIOS settings: hda:DMA, hdb:DMA
 [26] ide0: VIA Bus-Master (U)DMA Timing Config Success
 [27]    ide0: BM-DMA at 0xe008-0xe00f, BIOS settings: hdc:DMA, hdd:DMA
 [28] ide1: VIA Bus-Master (U)DMA Timing Config Success
 [29] hda: ST34321A, ATA DISK drive
 [30] hdb: CD-ROM TW 240D, ATAPI CDROM drive
 [31] ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
 [32] hda: ST34321A, 4103MB w/128kB Cache, CHS=523/255/63, UDMA
 [33] hdb: ATAPI 24X CD-ROM drive, 120kB Cache
 [34] Uniform CDROM driver Revision: 2.54
 [35] Floppy drive(s): fd0 is 1.44M
 [36] PPP: version 2.3.3 (demand dialling)
 [37] TCP compression code copyright 1989 Regents of the University of California
 [38] PPP line discipline registered.
 [39] Partition check:
 [40]  hda1 hda2 hda3 hda4
 [41] VFS: Mounted root (ext2 filesystem) readonly.
 [42] Freeing unused kernel memory: 48k freed
 [43] Adding Swap: 40156k swap-space (priority -1)

       Figura 13.1: Mensajes del kernel en la etapa de configuracion
                    de dispositivos.

A continuacion vamos a detallar las lineas mas importantes:

 * 01 Nos muestra la version del kernel, en este caso 2.2.5 y la fecha
       en la que se compilo el kernel.

 * 05 El kernel nos muestra la cantidad de memoria detectada en el
       sistema. En este caso 96 Mb.

 * 06 El kernel nos informa que procesador encontro.

 * 09 El kernel nos informa de la norma POSIX que soporta.

 * 10 El kernel nos informa de la deteccion de un bus PCI.

 * 13-14-15-16 En estas lineas se informa de la incializacion de los
                protocolos de red, en este caso TCP/IP.

 * 17-22 El kernel nos informa de la deteccion de un puerto paralelo
          que lo llama parport0 y trabaja en el puerto 0x3bc. Luego ese
          puerto es asignado a lp0.

 * 18 El kernel detecta un mouse PS/2 conectado al sistema.

 * 19-20-21 El kernel nos informa de la inicializacion de los puertos
             serie. En este caso encuentra dos ttyS00 y ttyS01, como
             puertos que soportan UART 16550A y trabajan en los puertos
             0x3f8 y 0x2f8 con interrupciones 4 y 3 respectivamente.

 * 23 Inicializacion del APM (Advanced Power Management).

 * 29-30 Deteccion de un disco rigido hda y de un CD-ROM hdb. En este
          caso el kernel creara un link simbolico /dev/cdrom para que
          apunte a /dev/hdb.

 * 35 Deteccion de una unidad de discos flexibles de 1.44 Mb fd0.

 * 36-37-38 Inicializacion y carga de los protocolos PPP (punto a
 punto).

 * 39-40 Chequeo de particiones, el kernel detecto cuatro particiones
          primarias (hda1, hda2, hda3, hda4).

 * 41 El kernel monta el sistema de archivos raiz, que debe ser de tipo
       ext2.

 * 43 El kernel inicializa el espacio de intercambio (swap) para
       utilizar una particion de 40 Mb.

13.3 PROCESO TRADICIONAL DE BOOTEO

Una vez que el kernel termina de cargar y configurar el hardware, incia
un proceso llamado init que es el "padre" de todos los procesos del
sistema y tiene asignado, por lo tanto, el numero identificatorio de
procesos (PID) 1.

El rol de este proceso es crear procesos de un script almacenado en el
archivo /etc/inittab.

13.3.1 NIVELES DE EJECUCION (RUNLEVELS)

Antes de explicar detalladamente el proceso de booteo del sistema,
vamos a presentar el concepto de nivel de ejecucion o runlevel, ya que
es importante para comprender el funcionamiento del proceso init.

Un runlevel es una configuracion de software que define un estado de
operacion del sistema que permite existir solo a determinado grupo de
procesos. Los procesos que init permite que existan en cada runlevel
son especificados en el archivo /etc/inittab.

En todo momento init se puede encontrar en un solo runlevel. Los
runlevels validos se encuentran en un rango de 0 a 6 y se detallan a
continuacion:

 * 0: halt - Detiene el sistema.
 * 1: modo unico usuario (single user)

 - Se utiliza para realizar tareas de mantenimiento y asegurarse de que
      ningun otro usuario esta trabajando en el sistema.

 * 2: Multiusuario sin NFS (sistema de archivos en red).
 * 3: (default) Multiusuario completo.
 * 4: -SIN USAR-
 * 5: Modo X11 (X Windows) - El sistema es iniciado directamente en modo
      grafico.
 * 6: reboot - Reincia el sistema.

Podemos cambiar en cualquier momento de runlevel (solo si tenemos
permiso para hacerlo) ejecutando el comando init con el numero de
runlevel como argumento:

 ==> init n

13.3.2 init TIENE LA POSTA

Una vez que se ejecuta init el mismo busca una linea en el archivo
inittab que especifique en que runlevel el sistema debe ser iniciado.
Esta linea es de la forma:

 id:n:initdefault:

Donde "n" es el numero de runlevel a iniciar. Una vez iniciado el
runlevel que corresponde init comienza la inicializacion del sistema
ejecutando la siguiente linea:

 si::sysinit:/etc/rc.d/rc.sysinit

13.3.3 INICIALIZACION DEL SISTEMA

El proceso de inicializacion del sistema se especifica en el archivo
/etc/rc.d/rc.sysinit y, entre otras cosas, se realiza lo siguiente:

 * Se setea el PATH inicial del sistema:

   PATH=/bin:/sbin:/usr/bin:/usr/sbin
   export PATH

 * Se definen los parametros de trabajo en red:

   if [ -f /etc/sysconfig/network ]; then
       . /etc/sysconfig/network
   else
       NETWORKING=no
       HOSTNAME=localhost
   fi

 * Se activan los espacios de intercambio:

   echo "Activating swap partitions"
   swapon -a

   NOTA: en la linea del echo, la podemos cambiar por algo asi:
         echo "Activando particiones swap"

 * Se realiza el chequeo del sistema de archivos raiz:

   if [ ! -f /fastboot ]; then
           echo "Checking root filesystems."
           fsck -V -a /
           ...
   fi

 * Se configuran los dispositivos Plug & Play:

   if [ -x /sbin/isapnp -a -f /etc/isapnp.conf ]; then
       if [ -n "$PNP" ]; then
           echo "Setting up ISA PNP devices"
           /sbin/isapnp /etc/isapnp.conf
       else
           echo "Skipping ISA PNP configuration at users request"
       fi
   fi

 * Se calculan las dependecias entre los modulos:

   if [ -x  /sbin/depmod -a -n "$USEMODULES" ]; then
       # Get ready for kerneld if module support in the kernel
       echo -n "Finding module dependencies"
       depmod -a
       echo ""
   fi

 * Se realiza el chequeo de los sistemas de archivos:

   # Check filesystems
   if [ ! -f /fastboot ]; then
           echo "Checking filesystems."
           fsck -R -A -V -a
   ...
   fi

 * Se montan los sistemas de archivos locales definidos en el archivo
   /etc/fstab.

    echo "Mounting local filesystems."
    mount -a -t nonfs

Una vez que se realizo la configuracion del sistema se pasa a iniciar los
procesos que estan permitidos en el runlevel iniciado.

13.3.4 INICIO DE PROCESOS RESPECTIVOS AL RUNLEVEL

Los procesos a iniciar respectivos a cada runlevel se encuentra
especificados en archivos que se encuentran en los directorios
/etc/rc.d/rc#.d donde "#" es el numero de runlevel.

El inicio de un runlevel tiene dos grandes partes:

 1- Ejecucion de los "kill scripts": Los kill scripts son scripts que se
                                     ocupan de detener servicios del
                                     runlevel actual.

 2- Ejecucion de los "start scripts": Los start scripts son scripts que
                                      se ocupan de iniciar los
                                      servicios del runlevel actual.


EL DIRECTORIO /etc/rc.d/init.d

En este directorio encontramos un archivo por cada servicio que
contiene un script y es ejecutable. Estos scripts se deben ejecutar con
un argumento obligatorio que puede ser cualquiera de los siguientes
valores:

 start    Con este argumento iniciamos el servicio.
 stop     Con este argumento detenemos el servicio.
 restart  Con este argumento reiniciamos el servicio (debe estar activo).
 status   Con este argumento preguntamos en que estado se ecuentra el
          servicio.


LOS DIRECTORIOS /etc/rc.d/rc#.d

Estos directorios son los directorios de los runlevels. Los mismos
contienen una serie de archivos que son links simbolicos a los scripts
que se almacenan en el directorio /etc/rc.d/init.d. En la figura 13.2a
vemos el contenido del directorio /etc/rc.d/rc3.d que corresponde al
runlevel multiusuario.

 # pwd
 /etc/rc.d/rc3.d
 # ls
 K15gpm        S30syslog      S50inet       S60rwhod       S85sound
 K60mars-nwe   S40atd         S55named      S70ypbind      S91smb
 S01kerneld    S40crond       S55routed     S75keytable    S99local
 S10network    S40portmap     S60lpd        S80sendmail
 S15nfsfs      S40snmpd       S60nfs        S85httpd
 S20random     S45pcmcia      S60rusersd    S85postgresql

         a. El contenido del directorio del runlevel 3.

 # pwd
 /etc/rc.d/rc0.d
 # ls
 K09keytable     K20nfs        K40snmpd    K60lpd        K95nfsfs
 K10named        K20rusersd    K50inet     K60mars-nwe   K97network
 K15gpm          K20rwhod      K50pcmcia   K65portmap    K98kerneld
 K15htppd        K30sendmail   K55routed   K70syslog     S00halt
 K15postgresql   K30ypbind     K60atd      K80random
 K15sound        K35smb        K60crond    K90killall

         b. El contenido del directorio del runlevel 0.

    Figura 13.2. El contenido de los directorios de los runlevels.

Es necesario analizar los nombres de los links simbolicos que
encontramos en los directorios de los runlevels. El nombre de estos
links consta de tres partes:

 1- Una letra mayuscula que puede ser "K" (Kill) o "S" (Start). Si
    encontramos una "K", significa que al entrar a ese runlevel se debe
    matar el servicio especificado por el link, por lo que se ejecutara
    el script respectivo en el directorio /etc/rc.d/init.d con el
    argumento stop. Si encontramos una "S", significa que al entrar a
    ese runlevel se debe iniciar el servicio indicado por el link y se
    ejecutara el script del directorio /etc/rc.d/init.d con el
    argumento start.

 2- Un numero de orden que especifica en que momento debe matarse o
    iniciarse el servicio especificado. Cuando init entra en un
    runlevel, primero se examina el directorio del runlevel buscando
    los links que comiencen con K y comenzando por el numero 00 se
    incrementa el valor y se van matando los servicios en ese orden.
    Luego de matar todos los servicios se comienza a iniciar los
    servicios que nos indican los links que comienzan con S. En este
    caso tambien se examinan los links en orden numerico ascendente. El
    orden de estos links es muy importante ya que para poder iniciar
    ciertos servicios, es necesario que se hayan iniciado otros
    anteriormente y para matar algunos servicios es necesario no haber
    matado a otros antes.

 3- El nombre del servicio es lo que forma el resto del nombre del link
    simbolico. Este nombre debe ser el nombre valido de un script que
    representa un servicio y que se encuentra en el directorio
    /etc/rc.d/init.d.

Como vemos en la figura 13.2a, el runlevel 3, solo mata algunos
servicios y luego inicia una gran cantidad de servicios, en cambio el
runlevel 0, que detiene el sistema, se ocupa de matar todos los
servicios y luego inicia un servicio llamado halt que veremos lo que
realiza mas adelante.

13.3.5 INICIO DE LOS PROCESOS DE INICIALIZACION DE TERMINALES

Una vez que el runlevel se encuentra activo, el proceso init se encarga
de iniciar un proceso pro cada terminal que se encuentre disponible
para trabajar en el sistema.

Cada uno de estos procesos toma una terminal y espera pedidos de inicio
de sesion consultando el estado de la terminal. Cuando un usuario se
loguea exitosamente se inicia un proceso de shell que sera utilizado
por ese usuario hasta que se termine su sesion en el sistema.

13.4 CARGA DEL PERFIL ESTANDAR

El administrador del sistema crea un perfil estandar para todos los
usuarios del sistema que es almacenado en el archivo /etc/profile. En
este archivo se setean una variedad de variables de entorno y se
realizan tareas de configuracion que es necesario que se lleven a cabo
para todos los usuarios.

Entre otras cosas se modifica el PATH, se setea el MANPATH (es el path
donde se encuentran las paginas manuales de los comandos), se setea el
prompt predeterminado (variable PS1), se setean las variables USER y
LOGNAME con el nombre de login del usuario que realiza el inicio de
sesion, y se pueden configurar scripts para ser ejecutados en el
momento que el usuario incie la sesion.

13.5 CARGA DE LOS PERFILES PERSONALIZADOS

Cada usuario puede personalizar el perfil dado por el administrador,
modificando el archivo .bash_profile que se encuentra en su directorio,
y que es cargado inmediatamente de que se cargue el perfil
predeterminado. Este archivo ademas carga el archivo .bashrc que
tambien posee configuraciones personales.

Usualmente los usuarios definen en este archivo variables de entorno
para uso personal, modifcan el PATH a gusto, agregan alias para los
comandos, etc.

13.6 DETENCION DEL SISTEMA

Al ejecutarse halt (init 0) o reboot (init 6), el sistema, luego de
matar todos los servicios, termina ejecutando el servicio halt que se
encuentra en el directorio /etc/rc.d/init.d. Este servicio es un script
que realiza lo siguiente:

 * Mata todos los procesos:

   # Kill all processes.
   [ "${BASH+bash}" = bash ] && enable kill

   echo "Sending all processes the TERM signal..."
   kill -15 -1
   sleep 5
   echo "Sending all processes the KILL signal..."
   kill -9 -1

 * Desactiva el espacio de intercambio y desmonta los sistemas de
 archivos:

   # Turn off swap, then unmount file systems.
   echo "Turning off swap"
   swapoff -a
   echo "Unmounting file systems"
   umount -a

 * Detener o rebootear (segun sea). El sistema nos muestra el mensaje

   The system is halted

   en caso de que se detenga el sistema, y ya nos encontramos en
   condiciones de cortar la energia y nos muestra el siguiente mensaje

   Please stand by while rebootin the system...

   antes de ejecutar la instruccion para que se reinicie la maquina.

En la figura 13.3 vemos un esquema de lo expuesto anteriormente.

                       .---------.
                       |   MBR   |
                       °---------°
                            |
                            |
                           \|/
                   .------------------.
                   | Sector de booteo |
                   |    particion     |
                   °------------------°
                            |
                            |
                           \|/
                       .---------.
                       | vmlinuz |
                       °---------°
                            |
                            |
                           \|/
                        .------.
                        | init |
                        °------°
                            |
                            |
                           \|/
                   .----------------.
                   | carga runlevel |
                   °----------------°
                   /        |       \
                 /          |         \____
               \|/         \|/            \|/
          .--------.    .--------.      .--------.
          | getty1 |    | getty2 |      | getty3 |
          °--------°    °--------°      °--------°
               |            |                |
              \|/          \|/              \|/
             @ @ @      .-------.          @ @ @
                        | login |
                        °-------°
                            |
                           \|/
                       .---------.
                       | profile |
                       °---------°
                            |
                           \|/
                    .---------------.
                    | .bash_profile |
                    °---------------°

     Figura 13.3: Esquema de estados del inicio del sistema.


CAPITULO 14

INSTALACION Y CONFIGURACION DE DISPOSITIVOS

14.1 MODEMS

14.1.1 PUERTOS SERIE Y MODEMS

Los modems funcionan exclusivamente a traves de un puerto serie de
nuestra computadora. Si el modem es externo, entonces el puerto serie
es fisico. Si el modem es interno, no se utiliza un puerto serie de la
maquina ya que el modem tiene el puerto serie como parte del mismo.

Los puertos serie, en Linux, son representados por los siguientes
archivos de dispositivos:
                  .----------.------------.
                  |  MS-DOS  |   Linux    |
                  |----------|------------|
                  |  COM1    | /dev/ttyS0 |
                  |  COM2    | /dev/ttyS1 |
                  |  COM3    | /dev/ttyS2 |
                  |  COM4    | /dev/ttyS3 |
                  °----------°------------°

14.1.2. MODEMS EXTERNOS

Para instalar un modem externo debemos seleccionar un puerto serie
(fisico) de la maquina y conectar al mismo el cable que va al modem
(cable serie). Para que el modem funciones debemos tener en cuenta que
debe ser detectado correctamente el puerto serie utilizado.

14.1.3 MODEMS INTERNOS

Un modem interno se instala agregando la tarjeta a la maquina en un
slot libre. Existen modems para los slots ISA y otros mas modernos para
los slots PCI. Los modems internos tienen el puerto serie dentro de la
tarjeta del modem y no necesitan utilizar un puerto serie (fisico) de
la maquina.

El seteo de la direccion de los puertos se realizaba con jumpers. Los
modems Plug & Play no utilizan jumpers y se configuran enviandoles
comandos. Estos comandos pueden ser enviados de tres formas:

 1. Una BIOS Plug & Play.
 2. El programa isapnp.
 3. Un S.O. (Sistema Operativo) PNP (Linux 2.2).

14.1.4 EL ARCHIVO /dev/modem

En algunas instalaciones se crean dos archivos de dispositivos
adicionales que son /dev/modem y /dev/mouse. Ambos son links simbolicos
a los dispositivos adecuados.

Debemos hacer que el link simbolico /dev/modem apunte al puerto serie
que corresponda antes de poder utilizar el modem. Esto es porque la
mayoria del software trabaja con este link simbolico.

14.1.5 PROBANDO EL MODEM

Una vez instalado y configurado el modem debemos revisar el archivo
/var/log/dmesg para ver si el modem es detectado al iniciar el sistema.
Debemos buscar las siguientes lineas de deteccion de puertos serie:

 Serial driver version 4.27 with no serial options enabled
 ttyS00 at 0x03f8 (irq = 4) is a 16550A
 ttyS01 at 0x02f8 (irq = 3) is a 16550A

Una vez que nos aseguramos de que el modem es detectado, podemos
utilizar el programa minicom para testear el modem.

14.2 IMPRESORAS

14.2.1 EL DISPOSITIVO PARPORT

En Linux los puertos paralelos se menejan con los dispositivos
/dev/lpi, donde "i" es el numero del puerto. /dev/lp0 equivale a LPT1
en MS-DOS, /dev/lp1 equivale a LPT2, etc.

En los kernels anteriores al 2.1.32 los dispositivos de puertos
paralelos se manejan con un driver llamado "lp" que tenia muchos
problemas y limitaciones. A partir del kernel 2.1.33 se integra un
nuevo driver de puertos paralelos llamado parport (parallel port).

Si queremos trabajar con impresoras conectadas a un puerto paralelo
debemos compilar el soporte para "parport" dentro del kernel o como
modulo para que el sistema detecte nuestro nuestros puertos paralelos.

Una vez que los puertos funcionan (verificarlo en /var/log/dmseg)
podemos pasar a la configuracion de la impresora.

14.2.2 IMPRESORAS SOPORTADAS

Practicamente cualquier impresora que se conecte a un puerto paralelo
podra ser utilizada con Linux. La mejor opcion es una impresora que
tenga soporte nativo para el formato PostScript ya que la gran mayoria
de los programas que trabajan sobre Linux generan impresion en ese
formato. Desafortunadamente es raro encontrar una impresora que soporte
PostScript que no sea laser.

Para solucionar este problema Linux provee un interprete en SW del
formato PostScript llamado GhostScript, que produce una salida
especifica para una gran cantidad de impresoras conocidas.

Para configurar la impresora podemos utilizar el programa printtool que
nos realiza una serie de preguntas acerca de las caracteristicas de
nuestra impresora y la configura por nosotros.

14.2.3 CONFIGURACION DEL lpd

La configuracion manual de las impresoras se realiza editando el
archivo /etc/printcap que contiene una serie de lineas que definen la
configuracion de cada impresora que tengamos en el sistema.

En la figura 14.1 vemos un ejemplo de archivo /etc/printcap.

 ##PRINTTOOL3## LOCAL cdj550 300x300 a4 {} Deskjet550 Default 1 1
 hp|lp:\
         :sd=/var/spool/lpd/hp:\
         :mx#0:\
         :sh:\
         :lp=/dev/lp0:\
         :if=/var/spool/lpd/hp/filter:
 ##PRINTOOL3## LOCAL bjc600 360x360 a4 {} BJC600 1 1
 canon:\
         :sd=/var/spool/lpd/canon:\
         :mx#0:\
         :sh:\
         :lp=/dev/lp1:\
         :if=/var/spool/lpd/canon/filter:

               Figura 14.1: Una archivo /etc/printcap.

En el archivo de la figura tenemos dos impresoras (una HP DeskJet 550 y
otra Canon Buble Jet 4300 - utiliza el driver de la BJC600 -). En la
primera linea de la configuracion de cada impresora vemos ciertas
opciones entre las cuales encontramos que: son locales (LOCAL), el
driver utilizado (cdj550 - bjc600), la resolucion (300x300 - 360x360),
el papel utilizado (a4 - a4). Vemos ademas que la impresora HP es la
predeterminada porque tiene la opcion "Default".

La siguiente linea define los nombres de la impresora. En el primer
caso se llama "hp" o "lp" (podemos poner alias separados del simbolo
"|") y en el segundo se llama "canon".

Dentro de cada entrada de impresora configuramos:

 * Spool Directory: (sd=) El directorio donde se guardan los trabajos a
                          imprimir.

 * Puerto Local: (lp=) El puerto paralelo utilizado.

 * Filtro de entrada: (if=) El filtro a utilizar (depende de la impresora
                            utilizada).

14.2.4 SOFTWARE DE SPOOLING

Para poder hacer funcionar bien la impresora en el sistema hay que
entender como funciona el software de spooling.

El software de spooling es el encargado de recibir los trabajos a
imprimir y encargarse de enviar la informacion a la impresora en el
orden que sea necesario (usualmente el primer trabajo que llega es el
primer trabajo en imprimirse).

El software de impresion en Linux es conocido como LPD (Line Printing
Daemon). Este software es una coleccion de programas que contiene:

 lpd: El demonio que realiza las tareas de spool.
 lpr: El comando que inserta un nuevo trabajo en la cola de spool.
 lpq: Nos muestra la lista de trabajos que se encuentran en la cola.
 lpc: El panel de control de lpd; podemos detener o iniciar una
      impresion, reordenar la cola, etc.
 lprm: Elimina un trabajo de la cola de spool.

Cuando el sistema se inicia, se ejecuta el demonio lpd como un servicio
activado en el runlevel. Este demonio escanea el archivo de
configuracion /etc/printcap para saber con que impresora debe trabajar.

Cada vez que un usuario quiere imprimir un trabajo, ejecuta lpr. Este
comando se comunica con el demonio a traves del socket /dev/printer y
le pasa el archivo a imprimir e informacion del usuario que manda a
imprimir. El demonio luego se ocupa de enviar el trabajo a la impresora
que corresponda.

14.3 TARJETAS DE SONIDO

14.3.1 INSTALANDO LA TARJETA DE SONIDO

Para instalar la tarjeta debemos seguir las intrucciones del manual de
la misma. Las tarjetas viejas tiene switchs o jumpers para configurar
los parametros de IRQ, DMA, etc. Debemos anotar los valores utilizados
para luego pasarselos al driver para que pueda trabajar.

Usualmente debemos utilizar los mismos puertos, IRQ y DMA que la placa
utiliza bajo MS-DOS. En otros casos, particularmente con las tarjetas
PnP, debemos utilizar parametros diferentes para que las cosas
funcionen en Linux. Puede ser necesario que experimentemos bastante
hasta lograr nuestra meta. :)

14.3.2 CONFIGURANDO EL KERNEL

Si no tenemos compilados los drivers que necesitamos para nuestra tarjeta
debemos seguir el proceso de compilacion seleccionando el driver adecuado
y compilandolo como parte del kernel o como modulo (recomendado).

14.3.3 BOOTEANDO LINUX Y TESTEANDO LA INSTALACION

Una vez que instalamos el nuevo kernel, debemos reinicar el sistema y ya
estamos en condiciones de testear el driver.

Si compilamos el driver como parte del kernel debemos revisar el archivo
/var/log/dmseg en busqueda de las siguientes lineas (en caso de tener una
Sound Blaster):

 Sound initialization started
 <Sound Blaster 16 (4.13)> at 0x220 irq 5 dma 1,5
 <Sound Blaster 16> at 0x330 irq 5 dma 0
 <Yamaha OPL3 FM> at 0x388
 Sound initialization complete

Estos datos deben equivaler a los que seleccionamos con los jumpers en
la tarjeta (en caso de que tenga).

Si no se muestra ningun mensaje, significa que el driver no es parte
del kernel. En este cado debemos chequear que hayamos instalado
correctamente el nuevo kenel.

Si los mensajes nos muestran lo siguiente:

 Sound initialization started
 Sound initialization complete

Quiere decir que ningun dispositivo fue detectado. Esto puede ser
porque no instalamos el driver adecuado, o que la tarjeta no esta
soportada, el puerto de trabajo de la tarjeta esta mal seteado o que la
tarjeta es PnP y no ha sido configurada.

El driver tambien puede mostrar algunos mensajes de error y
advertencias cuando se inicia. Debemos tener en cuenta estos errores y
anotarlos en caso de encontrarlos.

En caso de que el driver se haya compilado como modulo, debemos
cargarlo y ver que nos informa. No olvidemos proveer al modulo con las
opciones necesarias:

 * io: Puerto de trabajo (en hexadecimal - ejemplo: 0x220).
 * irq: Interrupcion de la tarjeta. * dma: Acceso directo a memoria
 (usualmente 1)

Como proximo chequeo debemos ver que contiene el archivo /dev/sndstat.
Este archivo es un archivo de dispositivo que nos provee informacion
adicional del estado del driver de sonido utilizado. Podemos averiguar
si el driver se inicio correctamente. Vemos un archivo /dev/sndstat de
muestra en la figura 14.2.

 # cat /dev/sndstat
 OSS/Free:3.8s2++971130
 Load type: Driver compiled into kernel
 Kernel: linux 2.2.5 #1 Tue May 11 20:15:59 ART 1999 i586
 Config options: 0

 Installed drivers:

 Card config:

 Audio devices:
 0: MAD16 WSS (CS4231A)

 Synth devices:

 Midi devices:

 Timers:
 0: System clock
 1: MAD16 WSS (CS4231A)

                  Figura 14.2: El archivo /dev/sndstat.


CAPITULO 15

ADMINISTRACION DEL SISTEMA

15.1 RESPONSABILIDADES DEL ADMINSTRADOR

La adminsitracion del sistema incluye todas las cosas que uno debiera
hacer para mantener a una (o varias) computadoras "utilizables".
Incluye cosas como:

 * Hacer backup de los archivos periodicamente y restablecerlos cuando
   sea necesario.

 * Montar sistemas de archivos (swap, de red, etc.).

 * Instalar software nuevo.

 * Adaptar el software a un nuevo ambiente (hardware, etc.).

 * Crear cuentas para los usuarios (y eliminarlas cuando no se
   necesiten mas).

 * Realizar chequeos a los sistemas de archivos.

 * Informar a los usuarios de nuevos servicios.

En resumen, es (o son, en el caso de que haya varias personas con la
responsabilidad de administrar un sistema) el encargado de mantener la
integridad y consistencia del sistema en general.

15.2 EL SUPERUSUARIO

En Linux (como en todos los sistema Unix) existe un usuario con
privilegios especiales, que le permiten precisamente realizar estas
tareas de administracion mencionadas. Este usuario es el llamado
"Superusuario", cuyo nombre de login es root. El supersuario es capaz
de realizar tareas que son prohibidas para usuarios ordinarios. Ademas,
algunos de los comandos ya vistos tienen un efecto especial cuando son
ejecutados con los privilegios del superusuario.

A diferencia de los usuarios ordinarios, quienes estan condicionados
por el sistema de modos de acceso a archivos (visto en 7.6), el
superusuario no tiene esta restriccion. Puede cambiar el modo de
cualquier archivo de cualquier manera. Una excepcion es sobre los
sistema de archivos remotos, sobre los cuales (en general) se le
otorgan permisos "en blanco", i.e. aunque un archivo tenga el permiso
de lectura para todo el mundo (others), root no lo puede leer.

Los comandos con privilegios de superusuarios pueden causar gran daño
si son ejecutados inapropiadamente, por esto es que se deberia confiar
confiar el password de root solo a gente con experiencia y responsable,
y ademas este grupo de personas deberia ser el menor posible.

15.2.1 EL COMANDO su

Existen dos maneras de obtener los privilegios de superusuario. Una
forma es realizar el login con el nombre especial root. La otra forma
de realizarlo es con el nombre normal y luego ejecutar el comando su
(superusuario). En cualquiera de los dos casos, el sistema pedira el
password del superusuario. En el caso de que el password sea correcto,
el sistema mostrara un prompt diferente al de los usuarios normales
(usualmente
#).

Por razones de seguridad, es preferible la segunda forma (utilizando el
comando su) a la primera. Esto se debe a que cada vez que se ejecuta
este comando, se registra el usuario que lo ejecuta, la fecha, y el
resultado (si tuvo o no exito).

El comando su permite a un usuario asumir la identidad de otro, tan
pronto como conozca su password. Como ya hemos dicho, es generalmente
usado por los administradores del sistema para obtener los privilegios
del superusuario. La sintaxis del comando es:

 su [-] [login_name]

Si se especifica un nombre de login, el comando pedira el password de
ese usuario, en caso contrario, se asume que uno quiere convertirse en
el superusuario y se le pide el password de root.

Por defecto, el directorio actual se mantiene como antes de haber
ejecutado el comando. Con la opcion '-' se procesa tambien el archivo
.login del nuevo usuario y la nueva shell comienza en el directorio
home del mismo.

15.3 ADMINSTRACION DE CUENTAS DE USUARIO

Una de las tareas del adminstrador del sistema es la adminstracion de
usuarios: agregar nuevos usuarios al sistema y borralos cuando ya no
sean necesarios.

Cuando una computadora es usada por varias personas, es necesario
diferenciarlas para, por ejemplo, mantener seguros sus archivos
privados. Para ello, a cada usuario se le otorga una cuenta en el
sistema. Esta no se compone solo de un nombre de usuario unico en el
sistema, que le permite a la persona loguearse en el sistema, sino
tambien del conjunto de todos los archivos, recursos e informacion
perteneciente al usuario (analogo a lo que ocurre con las cuentas
bancarias).

Al agregar un mnuevo usuario, hay una serie de puntos a tener en
cuenta:

 Nombre de usuario: Es un nombre que identificara al usuario en el
                    sistema. Se debe elegir un nombre que no este
                    actualmente en uso. Las convenciones mas usadas
                    son: usar el apellido, la primer inicial y el
                    apellido, las iniciales, etc. Tenes que tener 8
                    caracteres como maimo de largo.

 Identificador de usuario (UID): Cada usuario se identifica a traves de
                                 un numero entero (usualmente entre 0 y
                                 65535), dado que mas facil computar
                                 numeros que texto. Una base de datos
                                 separada del kernel asocia cada numero
                                 con un nombre textual (nombre de
                                 usuario). En general, los numeros
                                 bajos se reservan para el sistema y
                                 cada administrador luego tomara una
                                 politica de asignacion de numero de
                                 usuario.

 Identificador de grupo (GID): A cada usuario se le asocia un numero de
                               grupo que representa el grupo por
                               defecto del usuario. El usuario puede
                               ser agregado a otros grupos. De acuerdo
                               a los permisos de Linux sobre archivos,
                               un usuario tiene los privilegios de
                               todos los grupos del cual es miembro,
                               todo el tiempo.

 Password: A cada usuario se le debe asignar un password inicial. Es
           posible agregar un usuario sin password, pero es muy
           peligroso desde el punto de vista de la seguridad. Un
           password puede ser, al igual que el nombre de usuario, de
           hasta 8 caracteres; ademas los adminsitradores pueden
           imponer otras restricciones como: tener por lo menos 6
           caracteres, no ser una palabra asociada al nombre de
           usuario, etc.

 Directorio Home: Se debe crear un directorio home para cada usuario
                  nuevo. El nombre del directorio se forma con el
                  nombre del directorio inmediatamente superior, donde
                  estan los directorios home de su sistema, mas el
                  nombre del usuario. Por ejemplo, si en nuestro
                  sistema tenemos sistema de archivos para los
                  directorios home de los usuarios llamado /home/users/
                  y agregamos un usuario bill, su directorio home sera
                  entonces /home/users/bill/.

 Shell: Se debe elegir un shell para el nuevo usuario. En la mayoria de
        los sistemas, existe una shell predominante. En dichos
        sistemas, se le asigna a todos los nuevos usuarios la shell
        predominante. Aunque se le puede asignar cualquier shell que
        este listada en el archivo /etc/shells, archivo que contiene
        una lista de shells permitidas y disponibles.

15.3.1 EL COMANDO adduser

El comando adduser crea una nueva cuenta de usuario usando los valores
especificados en la linea de comandos y los valores por defecto del
sistema. La nueva cuenta se agrega a los archivos de sistema, se crea
el directorio home, se copian los archivos de inicio, dependiendo de
las opciones de la linea de comandos.

Algunas de las opciones que se le agregan a la linea de comandos son:

 -d home.dir

 El nuevo usuario se crea usando home.dir como nombre del directorio
 home. La opcion por defecto es agregar el nombre de usuario al nombre
 del directorio home default (ej: /home/users) y usarlo como nombre del
 directorio home del usuario.

 -g initial.group

 El nombre o el numero del grupo inicial para el usuario. El grupo debe
 existir. El numero default de grupo es 1.

 -G group,[...]

 Una lista suplementaria de grupos de los cuales el nuevo usuario es
 miembro tambien. Tiene las mismas restricciones que los grupos en la
 opcion -g. El valor por defecto es que el usuario pertenezca solo al
 grupo inicial A.

 -s shell

 El nombre de la shell del usuario. Si este campo esta en blanco, el
 sistema le otorga la shell por defecto.

 -u uid

 El valor numerico del UID. Debe ser unico y no negativo. La opcion por
 defecto es usar el ID mas pequeño mayor a 99 y mayor a cualquier UID
 de otro usuario. Los valores entre 0 y 99 estan reservados para
 cuentas del sistema.

15.3.2 LOS GRUPOS DE USUARIOS

Cada usuario puede pertenecer a uno o mas grupos. La importancia de las
relaciones de grupos recae en los permisos de los archivos. Cada
archivo pertenece a un grupo de usuarios y tiene ciertos permisos que
determinan los privilegios que tienen los usuarios que pertenecen a ese
grupo. De esta forma podemos lograr que se comparta informacion en el
sistema entre varios usuarios.

Existen varios grupos definidos por el sistema como son: bin, mail,
sys, etc.

Los usuarios ordinarios no deben pertenecer a estos grupos; se utilizan
para controlar el acceso del sistema a los archivos. Los usuarios
pueden pertenecer a un grupo llamado users o podemos crear varios
grupos si es necesario.

El archivo /etc/group contiene la informacion relativa a los grupos. El
formaro es el siguiente:

 group name:password:GID:miembros

Veamos un ejemplo de un archivo /etc/group en la figura 15.1.

 root::0:root
 bin::1:root,bin.daemon
 daemon::2:root,bin,daemon
 sys::4:root,adm,daemon
 tty::5:
 disk::6:root
 lp::7:daemon,lp
 mem::8:
 kmem::9:
 wheel::10:root
 mail::12:mail,users,kmem
 news::13:news
 uucp:14:uucp
 man::15:
 games::20:
 gopher::30:
 dip::40:
 ftp::50:
 nobody::99:
 users::100:tony,juan,fede,pablo,nukem
 floppy:x:19:
 postgres:x:101:

              Figura 15.1: Un archivo /etc/group.

El primer grupo root es un grupo reservado para la cuenta del
administrador. El grupo users que tiene GID 100 es el grupo
predeterminado para los usuarios y los usuarios tony, juan, fede, pablo
y nukem pertenecen a este grupo.

Tambien es posible agregar todo un grupo dentro de otro. Para esto
incluimos en la lista de otros miembros el nombre del grupo. Asi todos
los miembros del grupo que incluimos seran tambien miembros del nuevo
grupo.

15.3.3 DIRECTORIOS "home"

Cada usuario tiene un directorio especial llamado "home" cuyo nombre es
igual al nombre del usuario. Cuando un usuario se loguea en el sistema,
es posicionado alli.

EL ESQUELETO

Cuando un nuevo directorio home se crea, se lo inicializa con los
archivos que estan en el directorio /etc/skel. El administrador del
sistema puede crear archivos en ese directorio para proveer un ambiente
adecuado a los nuevos usuarios.

Sin embargo, es aconsejable mantener el directorio /etc/skel lo mas
reducido posible, aplicando las configuraciones globales a todo el
sistema en archivos tales como el /etc/profile.

15.4 CHEQUEO DE LOS SISTEMAS DE ARCHIVOS.

15.4.1 EL COMANDO fsck

El comando fsck se utiliza para verificar y arreglar sistemas de
archivos. Se pueden verificar uno o mas sistemas de archivos
individualmente especificando sus nombres en la linea de comandos. Si
estos pertenecen a distintos dispositivos fisicos fsck tratara de
realizar el chequeo en paralelo.

La sintaxis de este comando es:

 fsck filesys

Donde filesys es, o bien el nombre del dispositivo (ej: /dev/hda1), o
bien su punto de montaje (ej: /usr/local).

Si el comando se ejecuta sin argumentos, fsck verifica todos los
sistemas de archivos especificados en el archivo /etc/fstab para ser
chequeados.

15.5 LOS MODOS setuid Y setgid

Ocasionalmente, hay programas (como los juegos) que necesitan acceder a
un archivo, mientras que ese archivo debe permanecer inaccesible
mientras no se este ejecutando dicho programa. Este accionar se logra
con los modos setuid y setgid.

Si un archivo de programa tiene el modo setuid, dicho programa "corre"
como si lo ejecutara el dueño (owner) del archivo ejecutable, sin
importar quien lo ejecute. Esto es, cualquier usuario que ejecute dicho
programa adquiere los privilegios del dueño, mientras el programa esta
en ejecucion.

El modo setgid es similar al anterior, solo que se adquieren los
privilegios del grupo del dueño del archivo, y no del usuario.

El dueño de un archivo puede setear los setuid y setgid mediante el
comando chmod. La forma de utilizar este comando es tratada en la
seccion 7.6.

El modo setuid se indica con una s en la posicion ejecutable (x) del
dueño.

 -rwsr-xr-x 1 root workers 12288 Nov 29 20:54 phonels

El modo setgid se indica con una s en la posicion ejecutable (x) del
grupo.

 -rwxr-sr-x 1 root workers 12288 Nov 29 20:54 phonels

15.6 EJECUCION DE PROGRAMAS EN INTERVALOS DETERMINADOS

15.6.1 EL PROGRAMA cron

El programa cron es un demonio, iniciado poco despues del arranca del
sistema, que se utiliza para ejecutar programas en momentos
especificados.

Cron lee los comandos de los archivos crontab almacenados en el
directorio /var/spool/cron/crontabs.

Cualquier usuario puede crear un archivo crontab utilizando el comando
contrab. Este archivo se nombra con el nombre del usuario y el se
convierte en su dueño.

La sintaxis de este comando es:

 crontab [-e] [-r] [-l]

La opcion -l muestra el contenido del archivo. La opcion -e permite
editar el archivo.

Cada linea del archivo especifica un comando y cuando deberia ser
ejecutado. Todos los comandos ejecutados a partir de un archivo crontab
se ejecutan con los privilegios y el ambiente del usuario dueño de ese
archivo. Finalmente, la opcion -r borra el archivo del directorio
/var/spool/cron/crontabs.

El formato de las lineas del archivo crontab es la siguiente:

 <minutos> <horas> <dia del mes> <mes> <dia de la semana> <comandos>

Vemos un ejemplo de un archivo crontab en la figura 15.2.

 0-59/5 * * * * /sbin/rmmod -a
 0,10,20,30,40,50 * * * * date > /dev/console

                Figura 15.2: Un archivo crontab.

La primera entrada hace que cada 5 minutos se ejecute el comando rmmod
-a que descargara los modulos no utilizados. La segunda entrada hace
que la fecha actual se muestre en la consola cada 10 minutos.


CAPITULO 16

EL SISTEMA DE VENTANAS X WINDOWS

El sistema de ventanas X Windows fue desarrollado en el Laboratorio de
Ciencias de la Computacion del Massachussetts Institute of Technology
(MIT) con la cooperacion de DEC en 1984. En septiembre de 1987 MIT
lanzo el primer release de X11. A partir de X11R2 (release 2) el
control del proyecto paso al "X Consortium" que se formo en enero de
1988.

Hoy, X Windows es desarrollado y distribuido por el X Consortium. La
version utilizada en Linux es XFree86 que es una coleccion de
servidores X para sistemas operativos de la familia Unix en plataformas
Intel x86. La version incluida en Linux 5.0 es la XFree86 X11R6
(release 6) como parte de la mayoria de las distribuciones.

16.1 REQUERIMIENTOS DE HARDWARE

Para poder correr el sistema de X Windows, necesitamos una maquina con,
al menos, 4 Mb de Ram (fisica) y 16 Mb de memoria virtual. Tengamos en
cuenta, que cuanto mas memoria fisica tengamos el sistema utilizara
menos el espacio de intercambio. Como el espacio de intercambio se
mantiene en disco, y este es mucho, pero mucho mas lento que la memoria
principal, necesitamos 8 Mb o mas de memoria fisica para correr X
Windows de manera mas confortable. Un sistema con 4 Mb correra, mas o
menos, 10 veces mas lento que uno con 8 Mb o mas.

La configuracion sugerida es un 486 o algun Pentium con al menos 8 Mb y
una tarjeta de video cuyo chipset sea soportado por XFree86. Para
aquellos que desean una performance optima se recomienda utilizar una
tarjeta moderna con acelerador grafico.

16.2 CONFIGURANDO XFREE86

Configurar el sistema de ventanas X Windows requiere que definamos los
parametros del siguiente hardware:

 * Mouse a utilizar.
 * Teclado (internacionalizacion).
 * Monitor.
 * Tarjeta de video.

El sistema de ventanas almacena toda la configuracion necesaria para
iniciarse en el archivo /etc/X11/XF86Config. En un comienzo, para
configurar el sistema de ventanas debiamos editar a mano este archivo
seteando una gran cantidad de opciones como pueden ser: protocolos de
mouse, relojes utilizados por la tarjeta de video, frecuencias del
monitor, resoluciones y profundidad de color, etc.

Este proceso era muy complejo y pocas veces resultaba que el sistema
funcionara correctamente. Hoy se pueden utilizar cualquiera de las
siguientes utilidades:

 * Xconfigurator: Programa que trabaja con una serie de menus y nos va
                  realizando preguntas relativas a la configuracion y
                  finaliza creando un archivo XF86Config con las opciones
                  seleccionadas.

 * XF86setup: Este programa realiza la misma tarea, con la unica
              diferencia de que funciona en modo grafico VGA y es mas
              amigable y facil de utilizar.

16.2.1 SELECCIONANDO LA TARJETA DE VIDEO

El programa nos dejera seleccionar una de las tarjetas de video que el
sistema de ventanas soporta. En el archivo /usr/X11/doc/AccelCards o en
/usr/X11/lib/X11/doc/AccelCards encontramos una lista con las tarjetas
soportadas por el sistema de ventanas. Es conveniente buscar alli y
cerciorarnos que de que esta soportada antes de iniciar la
configuracion.

Una vez seleccionada la tarjeta, debemos elegir el monitor adecuado.

16.2.2 SELECCIONANDO EL MONITOR

El programa nos mostrara una gran lista de monitores de la cual podemos
elegir uno de ellos. El sistema de ventanas soporta, entre otros,
monitores Acer, Dell, Hitachi, IBM, NEC Multisync, PHILIPS, Samsung,
Sony, ViewSonic, etc. Si el monitor no se encuentra listado podemos
elegir "Generic Monitor" o "Custom". Si elegimos el segundo, deberemos
seleccionar que tipo de monitor tenemos. El programa nos dejara
seleccionar de una lista de monitores. En general seleccionaremos uno
de los siguientes:

 Super VGA, 1024x768 @ 87 Hz interlaced, 800x600 @ 56 Hz : Super Vga
     comunes entrelazados que soportan 1024x768.

 Non-Interlaced SVGA, 1024x768 @ 60 Hz, 800x600 @ 72 Hz : Super VGA (no
     entrelazados) que soportan 1024x768.

   NOTA: Es muy importante no seleccionar un tipo de monitor que tenga
         un rango de frecuencia horizontal mas alto que el del monitor
         que tenemos, ya que podemos arruinar el mismo.

16.2.3 SELECCIONANDO LA MEMORIA DE LA TARJETA DE VIDEO

A continuacion el programa nos pide que ingresemos la cantidad de
memoria de nuestra tarjeta de video. Esto es necesario para que en la
etapa de seleccion de modos y resoluciones se muestren los modos
correctos.

16.2.4 SELECCIONANDO EL "clockchip"

Luego el programa de configuracion nos pide que seleccionemos el
clockchip de nuestra tarjeta. Para la mayoria de las tarjetas de video
actuales no es necesario especificar un clockchip, pero debemos
averiguar en los manuales de nuestra tarjeta si la misma tiene un
clockchip de los que el programa nos lista para asi seleccionar el
correcto.

16.2.5 SELECCION DE LOS MODOS GRAFICOS

El programa realizara una tarea de autodeteccion de los modos que la
tarjeta de video soporta y nos informara del modo con resolucion mas
alta y mayor profundidad de color que pudo encontrar. Este sera el modo
predeterminado, pero podemos cambiarlo si no nos conforma.

16.2.6 RESOLUCION VIRTUAL

Si seleccionamos un modo grafico que no utiliza la totalidad de la
memoria de nuestra tarjeta de video, el sistema de ventanas se
configurara para utilizar resolucion virtual. La resolucion virtual
hace que tengamos un escritorio mas grande que el seleccionado, pero
virtual ya que moviendo el mouse a lo largo y a lo ancho de la pantalla
iremos descubriendo el resto del escritorio.

Para aquellos que no desean este tipo de resoluciones podemos
desactivarlas editando el archivo /etc/X11/XF86Config y remover todas
las lineas que especifican Virtual.....

Vemos un ejemplo en la figura 16.1

 ....
 # The Colour SVGA server

 Section "Screen"
     Driver      "svga"
     # Use Device "Generic VGA" for Standard VGA 320x200x256
     #Device     "My Video Card"
     Monitor     "My Monitor"
     Subsection "Display"
         Depth       16
         Modes       "800x600"
         ViewPort    0 0
         Virtual     "1024x768"
     EndSubsection
 EndSection
 ....

           Figura 16.1: Una seccion del archivo XF86Config

16.3 EJECUTANDO XFree86

Una vez configuado el sistema de ventanas, estamos listos para
ejecutarlo. Como primer medida, debemos asegurarnos de que el
directorio /usr/X11R6/bin forme parte de nuestro PATH.

El comando que inicia el sistema de ventanas es el siguiente:

 ==> startx

A continuacion el sistema intenta iniciarse en el modo especificado en
la configuracion. Si el sistema no fue configurado correctamente,
entonces el servidor X SVGA fallara y nos comunicara un error.

Si el servidor X se inicia con exito el programa xinit toma el control
e inicializa el sistema de ventanas.

16.3.1 EL PROGRAMA xinit

El programa xinit (X Windows System Initializer) se ocupa de iniciar el
sistema de ventanas. Realiza todas las tareas necesarias para
inicializar el sistema de ventanas correctamente.

Este programa escaneara el directorio home del usuario que inicio el
sistema de ventanas buscando el archivo .xinitrc.

16.3.2 EL ARCHIVO .xinitrc

Este archivo se ejecutara como un script de shell y su funcion es
iniciar programas clientes del sistema de ventanas. Usualmente se
utilza para iniciar el Window Manager (ver seccion 16.4) seleccionado y
algunos programas que el usuario quiera iniciar automaticamente.

Cada usuario puede editar este archivo a gusto para satisfacer sus
necesidades. Asi cada usuario cada usuario puede seleccionar que window
manager quiere utilizar, que programas quiere iniciar, etc.

16.4 EL "WINDOW MANAGER"

El window manager es la principal interfaz entre el sistema de ventanas
X Window y el usuario. Sin un window manager seria muy dificil de
utilizar y realmente no seria una herramienta productiva.

El window manager, usualmente, provee la siguiente funcionalidad extra
al sistema de ventanas:

 * Bordes de ventanas.
 * Menus, iconos.
 * Escritorios virtuales (desktops - workspaces).
 * Barra de ventanas, barras de tareas.
 * Personalizacion de todos estos puntos.

Algunos sistema de ventanas, van mas alla, ya que como parte de los
mismos tenemos aplicaciones especiales, herramientas de configuracion y
personalizacion, etc. En estos casos es usual hablar de Entornos y no
de Windows Managers.

La eleccion del window manager puede influenciar dramaticamente el
placer de nuestra experiencia de trabajo con el sistema de ventanas X
Window. Al trabajar en el sistema de ventanas invertimos mucho tiempo
manipulando ventanas y seguramente no queremos una interfaz que sea muy
incomoda o que no nos permita personalizarla. Algunos window managers
son extremadamente personalizables y nos pueden hacer sentir la ilusion
de que tenemos un nuevo sistema operativo.

16.4.1 FVWM/FVWM2/FVWM95

FVWM (F Virtual Window Manager) es el window manager original y mas
utilizado en el ambiente Linux. La version 2 (FVWM2) es el resultado de
una gran desarrollo y goza de una excelente estabilidad y de mucha
mejor flexiblilidad al trabajar.

Este window manager es considerado el gran favorito ya que se provee
como el window manager estandar en muchas distribuciones y los usuarios
de Linux lo han adoptado como el window manager perferido.

16.4.2 KDE

El entorno de escritorio KDE (KDE Desktop Environment) forma parte de
una segunda generacion de window managers para Linux. Es mas que un
window manager, es una coleccion de herramientas y utilidades que
funcionan muy bien interoperando.

KDE encabeza un proyecto y gran ciclo de desarrollo y no es
completamente estable todavia, pero apunta a ser todo lo que el usuario
necesita para trabajar.

KDE esta desarrollado sobre el kit QT, que es un conjunto de librerias
graficas muy importante en Linux.

Una cita de la pagina web de KDE:

 "KDE es un escritorio completamente nuevo que incorpora una larga
  suite de aplicaciones a las estaciones de trabajo Unix. KDE incorpora
  un window manager, un explorador de archivos (file manager), un
  centro de control (control center), y muchos otros componentes que
  uno espera encontrar en un entorno de escritorio contemporaneo. La
  verdadera potencia de este excepcional entorno es la
  interoperablilidad de sus componentes."

16.4.3 WINDOW MAKER

Este es un sistema de ventanas muy moderno con un "look" muy atractivo.
Es uno de los window managers mas faciles de configurar y muy facil de
usar. Soporta temas de escritorios (fondos de pantalla, iconos, bordes,
etc.) los cuales pueden ser cambiados muy facilmente y un gran conjunto
de caracteristicas que lo hacen uno de los window managers mas
atractivos.

Es por esto que este window manager esta ganando adeptos y esta siendo
muy recomendado por los usuarios de Linux.

A partir de la version 0.50, Window Maker nos permite ser utilizado en
combinacion con las herramientas de KDE que son muy utiles y proveen
una gran funcionalidad extra al entorno.

Una cita de la pagina web de Window Maker:

 "Window Maker es un window manager para el sistema de ventanas X11
  diseñado para otorgar soporte de integracion adicional para las
  aplicaciones GNUStep. Trata de emular el elegante "look" de la
  interfaz grafica de NEXTSTEP(tm). Es relativamente rapido, rico en
  caracteristicas, y muy facil de configurar y utilizar."

16.5 INICIANDO EL SISTEMA EN RUNLEVEL 5

Al iniciar el S.O. de forma predeterminada en el runlevel 5 accederemos
a una interfaz grafica (llamada xdm) que nos permite realizar el
proceso de login graficamente e inmediatamente accedemos al sistema de
ventanas bajo nuestra configuracion personal, es decir el window
manager que elegimos y las aplicaciones que se deben iniciar al entrar.

16.5.1 EL PROGRAMA xdm

El programa que se inicia como ultimo paso de la inicializacion del
sistema en el runlevel 5 es xdm (X Display Manager). Se utiliza para
proveer servicios de login a los usuarios en modo grafico.

Este programa benficia al usuario ya que es muy facil de utilizar y
automaticamente ingresamos (luego de loguearnos) en nuestro entorno de
escritorio.

Una vez que el usuario se logue exitosamente, se ejecuta el script
Xstartup como el usuario root y luego se ejecuta el script Xsession
como el usuario. Usualmente este script ejecuta otro llamado .xsession
que se encuentra en el directorio home del usuario.

16.5.2 EL ARCHIVO .xsession

Si el sistema se inicia de esta forma debemos configurar nuestro
entorno en el archivo .xsession. Su funcion es exactamente la misma que
la del archivo .xinitrc pero con la diferencia de que este se utiliza
al loguearse a traves de xdm.


16.6 APLICACIONES UTILES PARA EL SISTEMA DE VENTANAS X WINDOW

Existen un gran numero de plicaciones (X clients) para el sistema de
ventanas X Window. Vamos a describir algunas de ellas:

 * rxvt: Emulador de terminal con soporte para colores. Muy sencillo y
         pequeño por lo que ocupa muy poca memoria.

 * gv (ghostview): Un programa para visualizar documentos PostScript y
                   en formato Adobe PDF.

 * xconsole: Programa para monitorear los mensajes de la consola del
 sistema.

 * xcalc: Calculadora cientifica para X Window.

 * glint: Herramienta grafica de configuracion de paquetes para
          sistemas basados en paquetes RPM.

 * xman: Browser de paginas manuales para el sistema de ventanas X
 Window.

 * xkill: Nos permite matar cualquier proceso que pertenece a una
 ventana.

 * xmixer: Herramienta para configurar la mezcladora de la tarjeta de
 sonido.

 * xplaycd: Reproductor de CD's de audio.

 * xv: Visualizador de imagenes de todos los formatos posibles.


APENDICE A

DIRECCIONES REALACIONADAS CON EL SISTEMA OPERATIVO LINUX

Sitio oficial del sistema operrativo Linux .. www.linux.org
Sitio oficial del kernel de Linux ........... www.kernel.org
Linux aplications (Aplicaciones Linux) ...... www.linuxapps.com
The K Desktop Environment (KDE) ............. www.kde.org
Enlightenment Window Manager ................ www.enlightenment.org
The Dock App Warehouse (para Window Maker) .. www.bensinclair.com/dockapp
The Linux Mall .............................. www.linuxaplications.com
Sitio Web de Red Hat ........................ www.redhat.com
Software gratuito para Linux ................ ftp://sunsite.unc.edu/pub/Linux
The LINUX HeadQuarter ....................... www.linuxhq.com
Netscape Web Site ........................... www.netscape.com
X Multimedia System (ex-X11amp) ............. www.xmms.org
Window Maker Web Site ....................... www.windowmaker.org
Debian Web Site ............................. www.debian.org