Sei sulla pagina 1di 115

PRCTICAS DE SISTEMAS OPERATIVOS

EDUARDO DOMNGUEZ PARRA


CARLOS VILLARRUBIA JIMNEZ
DEPTO. DE TECNOLOGAS Y SISTEMAS DE INFORMACIN
E. S. de INFORMTICA
UNIV. de CASTILLA - LA MANCHA
CIUDAD REAL
Prefacio
Presentamos aqu un breve manual con material bsico para el desarrollo del programa
de prcticas de un primer curso de Sistemas Operativos en las titulaciones de Ingeniera en
Informtica, Ingeniera Tcnica en Informtica de Sistemas e Ingeniera Tcnica en Informtica
de Gestin. No ha sido nuestra intencin desarrollar un manual completo de uso del shell bash,
del compilador C de GNU, del depurador gdb de GNU o de la utilidad make de GNU; para ello
remitimos al lector a la abundante y, en muchos casos, excelente bibliografa que existe sobre
estos temas, sino ofrecer, en el menor nmero de pginas posible, un material didctico que
permita a un alumno de primer curso de Sistemas Operativos en cualquiera de las titulaciones
de Ingeniera Informtica, tomar contacto y explorar productivamente las capacidades de un
sistema tpico trabajando sobre un terminal alfanumrico.
Los autores desean agradecer su colaboracin a todos los compaeros que han participado
con ellos en la docencia de la asignatura de Sistemas Operativos en la Escuela Superior de
Informtica de la Universidad de Castilla - La Mancha, y especialmente a los profesores asociados
que como S. Garca Talegn, han desarrollado tareas correspondientes a dicha docencia durante
los ltimos cursos acadmicos o las desarrollan en la actualidad.
Del mismo modo, los autores queremos agradecer a nuestros alumnos el inters que estas
cuestiones suscitan en ellos, ya que ello es lo que nos ha animado a producir un material que
esperamos que contribuya a facilitar en lo posible su trabajo.
Ciudad Real, Septiembre de 2008.
Los autores.
i
ndice general
Prefacio i
I El shell bash 1
1. Introduccin 3
2. Primeros pasos con el shell bash 5
2.1. Comienzo y terminacin de sesin (login, exit, shutdown) . . . . . . . . . . . . 5
2.2. Escritura de rdenes en UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1. Formato de las rdenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.2. Efecto de las opciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.3. Problemas de paginacin (more, less) . . . . . . . . . . . . . . . . . . . . 11
2.3. Informacin de ayuda sobre las rdenes UNIX (man) . . . . . . . . . . . . . . . 12
2.4. Sugerencias (cal, date, who, whoami, users, clear, passwd) . . . . . . . . . . 15
3. El sistema de archivos 17
3.1. Caractersticas del sistema de archivos en UNIX (pwd, cd) . . . . . . . . . . . . 17
3.2. El shell y los metacaracteres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3. El editor de texto joe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.4. Operaciones bsicas en el sistema de archivos . . . . . . . . . . . . . . . . . . . . 21
3.4.1. Creacin y eliminacin de archivos y directorios (rm, mkdir, rmdir) . . 21
3.4.2. Exploracin del contenido de un directorio (ls) . . . . . . . . . . . . . . . 22
3.4.3. Copia, movimiento y cambios de nombre (cp, mv) . . . . . . . . . . . . . 24
3.4.4. Exploracin del contenido de un archivo (cat, head, tail) . . . . . . . . . 25
3.4.5. Cambios en el contenido de un archivo (tee) . . . . . . . . . . . . . . . . 26
3.4.6. Estadsticas sobre el contenido de un archivo (wc) . . . . . . . . . . . . . 26
iii
iv NDICE GENERAL
3.4.7. Actualizacin de los atributos de fecha y hora de un archivo (touch) . . . 26
3.4.8. Enlaces (ln) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.5. Permisos en el sistema de archivos . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.5.1. Cambios de propietario y grupo (chown, chgrp) . . . . . . . . . . . . . . 28
3.5.2. Cambios de permisos (chmod) . . . . . . . . . . . . . . . . . . . . . . . . 29
4. Operaciones especiales asociadas a las rdenes del shell 33
4.1. Variables de shell (set, export, echo) . . . . . . . . . . . . . . . . . . . . . . . . 33
4.1.1. El entorno de una orden (env) . . . . . . . . . . . . . . . . . . . . . . . . 34
4.1.2. Path de los ejecutables del shell (which) . . . . . . . . . . . . . . . . . . 34
4.2. Redireccin de la entrada, la salida y la salida de error estndares . . . . . . . . 34
4.3. Agrupacin y encadenamiento de rdenes . . . . . . . . . . . . . . . . . . . . . . 35
4.3.1. Ejecucin en segundo plano . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.4. Creacin de shells hijos (sh) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5. Otras rdenes tiles 39
5.1. Bsqueda de informacin en el sistema de archivos . . . . . . . . . . . . . . . . . 39
5.1.1. Bsqueda de archivos por sus atributos (nd, locate) . . . . . . . . . . . 39
5.1.2. Bsqueda de archivos por su contenido (grep) . . . . . . . . . . . . . . . 43
5.2. Manipulacin de archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
5.2.1. Compresin de archivos (gzip) . . . . . . . . . . . . . . . . . . . . . . . . 44
5.2.2. Serializacin de archivos (tar) . . . . . . . . . . . . . . . . . . . . . . . . 44
5.2.3. Ordenacin de lneas en archivos (sort) . . . . . . . . . . . . . . . . . . . 45
5.2.4. Sumas de comprobacin en archivos (md5sum) . . . . . . . . . . . . . . 46
5.3. Miscelnea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.3.1. Informacin sobre el sistema de archivos (df, du) . . . . . . . . . . . . . . 46
5.3.2. Determinacin del tiempo consumido por una orden (time) . . . . . . . . 47
5.3.3. Determinacin de la memoria disponible (free) . . . . . . . . . . . . . . . 48
5.3.4. Determinacin de la actividad de los usuarios (w) . . . . . . . . . . . . . 48
6. Control de procesos en UNIX 49
6.1. Informacin sobre procesos (ps) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
6.2. Control de trabajos (jobs, fg, bg, kill) . . . . . . . . . . . . . . . . . . . . . . . 49
6.3. Otras operaciones con procesos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
6.3.1. Espera durante un tiempo determinado (sleep) . . . . . . . . . . . . . . . 51
6.3.2. No eliminar un proceso al cerrar la sesin (nohup) . . . . . . . . . . . . . 51
6.3.3. Envo de seales a un proceso (kill) . . . . . . . . . . . . . . . . . . . . . 51
NDICE GENERAL v
II Uso del compilador C de GNU 53
7. Introduccin 55
7.1. Obtencin de un ejecutable a partir de los archivos fuente . . . . . . . . . . . . . 55
7.1.1. Preproceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.1.2. Compilacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.1.3. Ensamblaje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
7.1.4. Enlace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
8. El compilador C de GNU 59
8.1. Uso de gcc mediante el shell UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . 59
8.2. Opciones de uso frecuente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
8.2.1. Opciones globales (-c, -S, -E, -o <outle>) . . . . . . . . . . . . . . . . 60
8.2.2. Opciones que controlan los mensajes de aviso (-W <warn>) . . . . . . . 60
8.2.3. Opciones que controlan el estndar utilizado
(-std = <standard>) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.2.4. Opciones que controlan la incorporacin de cdigo para depuracin (-g,
-ggdb) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.2.5. Opciones que describen los directorios de residencia de las cabeceras (-
I<dir>) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.2.6. Opciones que describen los directorios de residencia de las bibliotecas (-
L<dir>) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.2.7. Opciones que describen las bibliotecas que deben usarse en el proceso de
enlace (-l<library>) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
III El depurador gdb de GNU 63
9. Introduccin 65
9.1. Un programa ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
9.2. Depuracin de un ejecutable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
10.El depurador gdb de GNU 71
10.1. Una sesin de depuracin con gdb . . . . . . . . . . . . . . . . . . . . . . . . . . 72
10.1.1. Argumentos de la lnea de rdenes . . . . . . . . . . . . . . . . . . . . . . 73
10.1.2. Puntos de ruptura (breakpoints) . . . . . . . . . . . . . . . . . . . . . . . 73
10.1.3. Ejecucin del programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
10.1.4. Otras rdenes tiles del depurador gdb . . . . . . . . . . . . . . . . . . . . 88
10.2. Sugerencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
vi NDICE GENERAL
IV La utilidad make de GNU 89
11.Introduccin 91
12.La utilidad make de GNU 93
12.1. Funcionamiento bsico de make . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
12.2. Sintaxis de los archivos makele . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
12.3. Sintaxis de las reglas de un archivo makele . . . . . . . . . . . . . . . . . . . . . 94
12.3.1. Disparo de una regla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
12.4. Ejemplo de ejecucin de la orden make . . . . . . . . . . . . . . . . . . . . . . . . 96
12.5. Reglas implcitas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Bibliografa 101
ndice de guras
2.1. Terminal sin sesin iniciada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2. Inicio de sesin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3. Sesin iniciada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4. Ejemplo de salida de una orden . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5. Ejemplo de salida de una orden errnea . . . . . . . . . . . . . . . . . . . . . . . 10
2.6. Ejemplo de salida de la orden cal sin opciones . . . . . . . . . . . . . . . . . . . . 11
2.7. Calendario del ao 2007 no paginado . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.8. Calendario del ao 2007. Pgina 1 . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.9. Calendario del ao 2007. Pgina 2 . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.10. Pgina 1 de manual para la orden cal . . . . . . . . . . . . . . . . . . . . . . . . 15
3.1. Pantalla inicial de joe para un archivo sin nombre y vaco . . . . . . . . . . . . . 20
3.2. Pantalla inicial de joe con el panel de ayuda visible . . . . . . . . . . . . . . . . . 20
3.3. Pantalla con la informacin de ls en formato largo . . . . . . . . . . . . . . . . . 23
4.1. Ejemplo de ejecucin en segundo plano . . . . . . . . . . . . . . . . . . . . . . . . 37
7.1. Operacin de preproceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
7.2. Operacin de compilacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
7.3. Operacin de ensamblaje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
7.4. Operacin de enlace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
9.1. Listado de errores de compilacin . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
9.2. Listado de errores de enlace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
9.3. Salida de la versin 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
10.1. Pantalla de presentacin del depurador gdb . . . . . . . . . . . . . . . . . . . . . 72
vii
viii NDICE DE FIGURAS
10.2. Paso de los argumentos de la lnea de rdenes . . . . . . . . . . . . . . . . . . . . 73
10.3. Punto de ruptura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
10.4. Ejecucin hasta el punto de ruptura . . . . . . . . . . . . . . . . . . . . . . . . . 75
10.5. Ejecucin de la sentencia 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.6. Ejecucin de la sentencia 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.7. Ejecucin de la sentencia 14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.8. Orden de salida del depurador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
10.9. Salida de la versin 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
10.10.Ejecucin del depurador con la versin 2 del programa . . . . . . . . . . . . . . . 81
10.11.Impresin del valor de una expresin . . . . . . . . . . . . . . . . . . . . . . . . . 81
10.12.Salida de la versin 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
10.13.Ejecucin del depurador con la versin 3 del programa . . . . . . . . . . . . . . . 84
10.14.Primera iteracin del bucle de impresin de argumentos . . . . . . . . . . . . . . 84
10.15.Traza de una funcin mediante la orden s . . . . . . . . . . . . . . . . . . . . . . 85
10.16.Primera ejecucin de la funcin PrintInforme . . . . . . . . . . . . . . . . . . . 86
10.17.Salida de la versin nal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
12.1. Salida de la orden make para el makele del listado 12.1 . . . . . . . . . . . . . . 98
ndice de listados
9.1. Programa ejemplo. Versin 0a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
9.2. Programa ejemplo. Versin 0b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
9.3. Programa ejemplo. Versin 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
10.1. Programa ejemplo. Versin 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
10.2. Programa ejemplo. Versin 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
10.3. Programa ejemplo. Versin nal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
12.1. Ejemplo de makele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
ix
ndice de algoritmos
1. Disparo de Regla(< objetivo >) . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
xi
Parte I
El shell bash
1
Captulo 1
Introduccin
El uso habitual de interfaces grcos para trabajar con ordenadores personales, as como
el de terminales con capacidad grca para operar en computadoras de todos los tamaos, no
ha eliminado, en el mbito profesional, la necesidad de usar los terminales alfanumricos para,
con el soporte de un shell adecuado, desarrollar tareas de procesamiento, particularmente en
computadoras remotas.
Sin embargo, esa utilizacin habitual de interfaces grcos de usuario, hace conveniente in-
cluir en el desarrollo prctico de la enseanza de grado algunas sesiones dedicadas a la descripcin
de un shell para el manejo de un sistema operativo a travs de un terminal alfanumrico, con
objeto de que el alumno no tenga que depender estrictamente de la disponibilidad de un interfaz
grco para poder desarrollar su trabajo.
Las breves pginas que siguen estn dedicadas al desarrollo de una somera descripcin de las
rdenes ms habitualmente utilizadas en el shell bash de UNIX (LINUX), y ello sin ocuparse
ms que de las opciones de mayor inters.
No trataremos aqu de describir exhaustivamente las capacidades del shell bash, sino de
proporcionar a los alumnos de un primer curso de Sistemas Operativos en las enseanzas de
Ingeniera en Informtica e Ingeniera Tcnica en Informtica, una gua elemental que les permita
iniciarse en el conocimiento y el uso de dicho shell, con objeto de facilitar una tarea, que,
efectuada directamente sobre la abundante bibliografa existente, desanima en muchos casos al
lector por el exceso de informacin que tiene que manejar.
De acuerdo con ese objetivo, no se abordar ninguna de las capacidades de programacin
del shell, dado que, en una primera etapa, no son imprescindibles.
Para obtener un buen rendimiento en el estudio de cualquier shell, es conveniente utilizar
una instalacin donde pueda usarse un terminal del tipo adecuado. Cualquier distribucin de
LINUX puede ser utilizada, e incluso, si no es UNIX el sistema operativo que habitualmente se
utiliza, un software de mquina virtual adecuado puede permitir al lector instalar una mquina
virtual con LINUX que funcione sobre su propio sistema, y sin cambios especiales en ste, usar
este manual para entrenarse en el uso de un terminal alfanumrico sobre UNIX.
La organizacin del manual en esta primera parte es la siguiente: En el captulo 2 se revisan
los primeros pasos necesarios para el uso del shell bash. En el captulo 3 se describen las rdenes
ms importantes para el manejo del sistema de archivos y el sistema de proteccin y se describe
3
4
el uso bsico de un editor de texto. En el captulo 4 se revisan algunas de las capacidades
del shell para el manejo de rdenes. En el captulo 5 se describen algunas rdenes de utilidad
suplementarias. Por ltimo, en el captulo 6 se trata el control de procesos mediante el shell
bash.
Captulo 2
Primeros pasos con el shell bash
2.1. Comienzo y terminacin de sesin (login, exit, shut-
down)
El modo bsico en el cual un usuario da rdenes a un sistema UNIX consiste en escribir
esas rdenes en el teclado de un terminal (un dispositivo de entrada/salida (E/S) que consta
de un teclado para escribir la orden y un dispositivo de salida para visualizar los resultados,
tpicamente una pantalla).
En LINUX (una implementacin del sistema operativo UNIX) hay disponibles (usando el
teclado y la pantalla del ordenador) seis terminales virtuales. Al arrancar el sistema, el terminal
activo es el 1 (tty1) pero en cualquier momento se puede usar otro cualquiera pulsando la
combinacin de teclas <Alt>-Fn, donde Fn es una de las teclas de funcin F1-F6.
En este manual mostraremos mediante imgenes la salida de pantalla del terminal con el que
estemos trabajando en un momento dado.
Por ejemplo en la gura 2.1 vemos la pantalla de un terminal (tty2) que tendramos si,
despus de arrancar el sistema pulsamos <Alt>-F2.
Cuando queramos indicar qu escribimos nosotros en el teclado usaremos frecuentemente la
notacin

I ns e r c i n de rdenes en e l t e c l ado del t er mi nal . . .


Antes de poder dar alguna orden al sistema es necesario abrir una sesin en un terminal.
Slo despus ser posible dar rdenes a travs de ese terminal.
Para abrir una sesin es necesario responder a las peticiones que nos har el proceso que, al
principio, se est ejecutando en el terminal (proceso login). Ese proceso requiere que nos iden-
tiquemos mediante nuestro identicador de usuario (login del usuario). Para nuestros ejemplos,
ese login ser habitualmente alumno.
5
6 2.1. Comienzo y terminacin de sesin (login, exit, shutdown)
Figura 2.1: Terminal sin sesin iniciada
Cuando tengamos que escribir cualquier informacin en el terminal, podremos editarla como
es habitual, movindonos mediante las teclas del cursor y borrando o insertando los caracteres
que necesitemos.
Una vez que la entrada est completa, pulsaremos la tecla de retorno de carro (<RET>).
Slo en ese momento obtendremos la correspondiente salida, que se ir escribiendo debajo de
nuestra entrada. Cuando se llega a la lnea nal de la pantalla, sta realiza el scroll conveniente
para que podamos ver la lnea nal de la salida.
As pues, si nosotros escribimos en la posicin del cursor en la gura 2.1

alumno
o el correspondiente identicador que nos hayan asignado, obtendremos en la pantalla la res-
puesta del proceso login de la gura 2.2, que consiste en una nueva peticin para que nosotros
escribamos una palabra clave (password) que permita al proceso login conrmar que somos quien
decimos ser (autenticacin). En nuestro caso escribiremos de nuevo

alumno
o la password que corresponda a nuestro login. El proceso login no escribe la password en
pantalla, ni caracteres de mscara que permitan siquiera contar los caracteres de la password.
Si la validacin resulta correcta obtendremos el resultado que se observa en la gura 2.3
2.1. Comienzo y terminacin de sesin (login, exit, shutdown) 7
Figura 2.2: Inicio de sesin
Figura 2.3: Sesin iniciada
8 2.1. Comienzo y terminacin de sesin (login, exit, shutdown)
Ahora, el proceso login ha creado un proceso shell, (abreviadamente un shell) que ser el
que se ocupe de que se ejecuten nuestras rdenes. No obstante, el shell es un intrprete que,
generalmente, no ejecuta por s mismo nuestras rdenes, sino que, despus de analizarlas, pone
en marcha programas especcos para ejecutar las diferentes rdenes.
A la secuencia de operaciones realizada hasta aqu se denomina en UNIX abrir una sesin.
Cuando hayamos terminado de trabajar con el terminal, debemos dar por terminada la
sesin, escribiendo

e xi t
lo cual nos llevar a la situacin de la gura 2.1. Nuestro shell ha terminado y se ha puesto
nuevamente el terminal bajo el control de un proceso login para permitir iniciar una nueva
sesin al mismo usuario o a otro.
No es necesario cerrar una sesin que tengamos abierta en un terminal para poder abrir
otra en otro terminal que tengamos inactivo. Por ejemplo, aqu, antes de cerrar la sesin en
tty2 podramos haber usado el terminal tty1 (pulsando <Alt>-F1) y abrir en l una nueva
sesin (del mismo modo que lo hemos hecho en el ejemplo previo). Si luego hubiramos vuelto
a pulsar <Alt>-F2 habramos obtenido de nuevo la pantalla del terminal tty2 tal como la
tuviramos cuando cambiamos de terminal. Esto nos permite trabajar hasta con seis sesiones
abiertas simultneamente.
El proceso de cerrar una sesin del shell no termina la ejecucin del sistema operativo. Si que-
remos dar de baja el sistema, por ejemplo porque tenemos que apagar la mquina, teclearemos
desde una sesin abierta como administrador del sistema (root)

shutdown h 0
lo cual cerrar todas las sesiones abiertas y dar de baja ordenadamente el sistema.
Resumiendo lo que hemos visto hasta aqu, el administrador del sistema, al darnos de alta
como usuarios (o, como se dice habitualmente, al abrirnos una cuenta), debe asignarnos un login
y una password que nos servirn para poder abrir sesiones en ese sistema UNIX.
Adems en UNIX hay diferentes programas de tipo shell, de modo que el administrador
tambin debe asignarnos, entre otras cosas que ya iremos precisando a lo largo de los captulos
siguientes, el programa shell que se usar por defecto para ejecutar nuestras rdenes cuando
abramos una sesin.
En estas lecciones se supondr siempre que el programa shell usado ser el shell bash. La
informacin de referencia para este shell puede ser consultada en [2], y es recomendable disponer
de la informacin de [4] como ayuda habitual.
Otros tipos de shell ejecutan las rdenes esencialmente de la misma manera que el shell bash,
pero dieren de ste en su forma de programacin.
2.2. Escritura de rdenes en UNIX 9
2.2. Escritura de rdenes en UNIX
2.2.1. Formato de las rdenes
Las rdenes que podemos escribir en el terminal, una vez que tengamos abierta una sesin,
pueden ser de muchas clases, pero su formato bsico es muy parecido en los distintos casos.
Una orden comienza por una palabra que identica la clase de operacin que debe hacerse y
que es denominada nombre de la orden. Es comn en la bibliografa denominar comando tanto
a la orden completa como a su nombre.
Despus, y separadas por uno o ms espacios del nombre de la orden, continan opcional-
mente uno o varios grupos de letras y/o cifras separados entre s por espacios y precedidos
habitualmente cada uno por un signo menos. Estos caracteres especican opciones que deben
ser tenidas en cuenta por el shell para la ejecucin de la orden.
Por ltimo y tambin opcionalmente y separados entre s y de las opciones por uno o ms
espacios, se encuentran series de caracteres que forman los objetivos de la orden. Habitualmente
son nombres de archivos y/o directorios sobre los que la orden debe operar.
En general, el aspecto de la orden sera
<nombre>[<opcin-1>]...[<opcin-m>] [<objetivo-1>]...[<objetivo-n>]
Un ejemplo de una orden tpica sera

c al m 6 2007
El nombre de la orden es aqu cal, las opciones se reducen a -m, mientras que los objetivos
de la orden son 6 2007.
Al escribir las rdenes debemos tener en cuenta que las letras maysculas y las minsculas
no son equivalentes.
Por otra parte, debemos recordar que una orden slo se ejecuta cuando pulsamos la tecla
<RET>, y que mientras no lo hagamos, podemos corregir los errores que hayamos cometido
al escribir. Una vez que pulsamos <RET>, el sistema intentar ejecutar la orden tal como est
escrita, y nos proporcionar la salida correspondiente.
En la gura 2.4 podemos ver la salida de la orden anterior, en la que el sistema nos propor-
ciona un calendario de Junio de 2007.
En cambio si escribimos

CAl m 6 2007
obtendremos la salida de la gura 2.5 en la que observamos el informe de error que nos indica
que la orden CAl no existe. El nombre correcto de la orden es cal.
En ambos casos, el shell queda disponible para que escribamos una nueva orden.
10 2.2. Escritura de rdenes en UNIX
Figura 2.4: Ejemplo de salida de una orden
Figura 2.5: Ejemplo de salida de una orden errnea
2.2. Escritura de rdenes en UNIX 11
Figura 2.6: Ejemplo de salida de la orden cal sin opciones
2.2.2. Efecto de las opciones
Veamos ahora cmo funcionan las opciones. La opcin -m indica que queremos que el ca-
lendario est ordenado de forma que en la primera columna del mes aparezcan las fechas de los
lunes. Si no usamos esa opcin, UNIX ordena el calendario de forma que en la primera columna
del mes aparezcan las fechas de los domingos, como es habitual en los pases anglosajones.
Si escribimos

c al 6 2007
obtendremos la salida indicada en la gura 2.6
2.2.3. Problemas de paginacin (more, less)
Hasta ahora las salidas de las rdenes que hemos obtenido tenan pocas lneas. Cuando la
salida tiene ms lneas de las que caben en una pantalla se plantea el problema de poder leer las
lneas a las que el scrolling ha hecho salir de la pantalla. Como ejemplo podemos ver la salida
de la orden

c al m 2007
tendramos la salida que se observa en la gura 2.7. En ella se observa que las las de texto
correspondientes a los primeros meses del ao 2007 no pueden leerse porque han salido por
12 2.3. Informacin de ayuda sobre las rdenes UNIX (man)
Figura 2.7: Calendario del ao 2007 no paginado
encima de la pantalla. De una salida que presente ese problema se dice que est no paginada,
es decir, que es necesario someterla a un proceso para partirla en pginas con objeto de poder
verla entera.
La forma de resolver este problema es enviar la salida de la orden cal a otra orden que sea
capaz de procesar una entrada sin paginar para producir una salida paginada. Una orden de ese
tipo recibe el nombre de paginador. En UNIX existen diferentes paginadores. Dos de los ms
comunes son more y less.
La forma de enviar la salida de una orden (en este caso cal) para ser usada como entrada
de otra (en este caso more) es usar el operador | (llamado operador pipe).
Si escribimos

c al m 2007 | more
obtendremos como salida la de la gura 2.8.
Ahora debemos ver la pgina siguiente pulsando la barra espaciadora. La pantalla tomar el
aspecto de la gura 2.9.
Podemos observar que la salida de la orden cal se ha completado porque el shell est espe-
rando (ha escrito ya el indicador alumno@ssoo:$)
2.3. Informacin de ayuda sobre las rdenes UNIX (man)
Las preguntas que nos hacemos ahora son
2.3. Informacin de ayuda sobre las rdenes UNIX (man) 13
Figura 2.8: Calendario del ao 2007. Pgina 1
Figura 2.9: Calendario del ao 2007. Pgina 2
14 2.3. Informacin de ayuda sobre las rdenes UNIX (man)
Cuntas y cules son las rdenes que podemos manejar con el shell?
Para una determinada orden cuntas y cules son las opciones disponibles, y cules son
el cometido de la orden y la salida que produce?
En el primer caso no hay una respuesta denida porque eso depende del tipo de UNIX, y,
dentro de un tipo determinado, de la conguracin de la instalacin en la que trabajemos. Ade-
ms, cualquier shell UNIX permite que el programador construya rdenes que el shell ejecutar
sin hacer ninguna diferencia con las que se entregan con el propio sistema. En todo caso se puede
responder que las rdenes bsicas son aproximadamente un centenar. En cuanto a cules son,
en estas pginas estudiaremos las ms importantes.
La respuesta a la segunda cuestin es ms sencilla. Existe en UNIX una orden que permite
al usuario obtener informacin de manual sobre cualquier orden, incluida ella misma. Esa orden
es man.
Cuando el usuario desea obtener informacin de manual sobre una determinada orden, debe
ejecutar una orden man con un objetivo que ser el nombre de la orden sobre la que se desea
obtener informacin.
Por ejemplo, si deseamos saber para qu sirve, cual es el formato o cules son las opciones
de la orden cal podemos escribir

man c al
y obtendremos una salida (paginada) que puede recorrerse hacia adelante o hacia atrs mediante
las teclas de movimiento habituales y cuya primera pgina est representada en la gura 2.10
Como la orden man produce una salida paginada y, al igual que otros paginadores, permite
avanzar y retroceder por ella, el shell debe ser avisado por el usuario de que ya ha terminado de
trabajar con esa salida. Para ello, el usuario debe pulsar la tecla q. Como respuesta, el shell
terminar la ejecucin de la orden man y escribir de nuevo el indicador del shell para informar
al usuario de que est esperando una nueva orden.
Naturalmente se puede obtener informacin de manual sobre la orden man escribiendo

man man
El formato de la orden man es

man [ opci n ] . . . [S <l i s t a desec >] [<sec >] <nombre >. . .


Se obtiene informacin de manual sobre los nombres que guren en la orden, relativa a las
secciones que se especiquen en la lista de secciones <lista-de-sec> o en el argumento <sec>.
<sec> es un nmero de seccin del manual. <lista-de-sec> es una serie de numeros de seccin
separados por el carcter :. Por defecto, si no se especica nmero de seccin, la informacin
corresponder a la seccin 1 (aunque eso puede depender de la conguracin del sistema).
Los contenidos de las secciones ms importantes del manual son
2.4. Sugerencias (cal, date, who, whoami, users, clear, passwd) 15
Figura 2.10: Pgina 1 de manual para la orden cal
1 rdenes normales del shell
2 Llamadas al sistema operativo
3 Funciones de la biblioteca estndar C
8 rdenes del shell especcas para la administracin del sistema
La opcin ms importante es
-a Por defecto, man terminar despus de mostrar la pgina de manual correspondiente al
nombre buscado, en la primera seccin en la que se encuentre. La opcin -a permite
obtener la informacin del resto de las pginas de manual que correspondan a ese nombre
en todas las secciones, y no slo de la primera que se encuentre
2.4. Sugerencias (cal, date, who, whoami, users, clear, passwd)
El lector debe ahora obtener informacin de manual y practicar el uso de las siguientes
rdenes del shell simples (las opciones ms importantes guran entre parntesis)
cal (3, -m, -y)
date
who (-m)
whoami
16 2.4. Sugerencias (cal, date, who, whoami, users, clear, passwd)
users
clear
passwd
Como manual simple de ayuda inicial sobre UNIX, puede consultarse [1].
Captulo 3
El sistema de archivos
3.1. Caractersticas del sistema de archivos en UNIX (pwd,
cd)
El sistema de archivos nativo de UNIX es un sistema jerrquico, en el que tanto los archivos
como los dems nodos presentes en el sistema, se encuentran organizados en directorios. La
jerarqua es nica, no hay una por cada unidad fsica.
Un directorio no es ms que un tipo de archivo especial, que contiene un asociacin entre
los identicadores (nombres) de los nodos (tpicamente archivos y otros directorios, pero no slo
ellos) descritos en l y los atributos de stos (propietario, tamao, permisos de uso, posicin en
el almacenamiento, . . . ).
Una referencia a un archivo (o a cualquier otro tipo de nodo) se realiza dando la serie de
nombres de directorio que describen un camino (path) que lleve hasta el nodo en la jerarqua
total, seguida del nombre del archivo (o del nodo de que se trate).
Los nombres de archivos y directorios en UNIX se pueden formar prcticamente con cualquier
serie de caracteres. No obstante, conviene tener en cuenta que la longitud total del path y el
nombre de un nodo est limitada (tpicamente a 256 caracteres). Por otra parte es inconveniente
usar caracteres especiales que no sean el signo menos, el de subrayado o el punto intercalados
en el los nombres, dado que algunos de los otros caracteres especiales pueden ser interpretados
de manera especial por el shell. Suele usarse como primer carcter una letra, pero ello no es
obligatorio. En UNIX los nombres no tienen ningn signicado especial para el sistema, aparte
de servir de identicadores, y, como siempre, las letras maysculas y las minsculas no son
equivalentes.
El path de bsqueda comienza en un directorio especial, denominado directorio raz, cuyo
nombre siempre es el carcter /. ste es el nico nodo que no se encuentra referenciado en
ningn directorio. Ese mismo carcter / se usa como separador entre los nombres de directorio
que forman el path y entre stos y el nombre del nodo.
En cada momento una aplicacin tiene asociado un directorio denominado directorio de
trabajo actual. Si una aplicacin referencia un nodo dando un path que no comience por el
carcter / (path relativo), el path completo (absoluto) del nodo se forma siempre anteponiendo
al path relativo el path del directorio de trabajo actual.
17
18 3.2. El shell y los metacaracteres
El directorio de trabajo actual al abrir una sesin del shell es un directorio asignado al
usuario por el administrador del sistema, que se denomina directorio home del usuario. Para el
usuario alumno que nos ha servido de ejemplo en la seccin 2.1 es /home/alumno.
Si tenemos que usar el nombre de nuestro directorio home como parte inicial de un path,
podemos usar como alias el carcter .
En cada directorio hay dos entradas cuyos nombres son . y .., que se reeren respectiva-
mente al propio directorio y al directorio antecesor en la jerarqua (directorio padre).
La orden del shell para saber cul es el directorio de trabajo actual en un momento dado es

pwd
Para cambiar el directorio de trabajo actual se usa

cd <nombrenuevodi r e c t o r i o act ual >


Por ejemplo, si nuestro directorio de trabajo actual es nuestro directorio home,
/home/alumno, la orden

cd . .
hara que nuestro nuevo directorio de trabajo actual fuese /home. Se ha citado el directorio
padre mediante un path relativo. El nombre completo del directorio que tomar la orden ser
entonces /home/alumno/..; comprubese usando la orden pwd.
En cualquier momento podemos hacer que nuestro directorio home vuelva a ser nuestro
directorio de trabajo actual mediante la orden cd sin argumentos.

cd
3.2. El shell y los metacaracteres
Como veremos en todo lo que sigue, muchos de los objetivos de las rdenes del shell son
nombres de archivos o directorios, y en la misma orden puede haber varios de estos objetivos.
Una forma de simplicar la escritura de las rdenes consiste en usar ciertos caracteres (me-
tacaracteres o caracteres comodn) para que el shell los interprete de modo especial, y ello le
permita generar diversos nombres objetivo a partir de ciertos patrones que escribimos en la lnea
de rdenes. As pues, una palabra que contenga estos caracteres se sustituye por una lista con
los nombres de archivo o de directorio que se ajusten al patrn.
Los metacaracteres ms usados son
3.3. El editor de texto joe 19
* Representa cualquier cadena (incluida la cadena vaca). El carcter . no es generado en las
sustituciones de * cuando est en la primera posicin del nombre
? Representa cualquier carcter
[<lista>] Representa cualquier carcter incluido en <lista>. En la lista se pueden poner ca-
racteres o bien intervalos con el comienzo y el nal separados por un signo menos
[!<lista>] Representa cualquier carcter que no pertenezca a <lista>.
3.3. El editor de texto joe
Hay muchas maneras de crear archivos durante una sesin de trabajo, pero una de las ms
frecuentes es utilizar un editor de texto para hacerlo.
En nuestro trabajo utilizaremos habitualmente el editor joe para esa tarea. joe es un editor
adecuado para usar en un terminal alfanumrico. Se trata de un editor de pantalla completa de
tipo WordStar.
La orden para la creacin de un archivo nuevo o bien para la edicin de uno ya existente es

j oe <nombredearchi vo>
El nombre de archivo es necesario slo si se va a editar un archivo existente. Si se trata de
un archivo nuevo, se puede no asignarle nombre hasta el momento de guardarlo.
En la gura 3.1 podemos ver la pantalla de trabajo de joe con una lnea de ayuda en la
parte superior y una lnea de estado en la inferior.
En la zona central el usuario puede escribir el texto del archivo en la forma usual.
joe es un editor con un interfaz unimodal, que admite multitud de rdenes mientras se
escribe el texto. Todas esas rdenes se dan mediante combinaciones especiales de teclas, pero
no es necesario recordarlas todas para trabajar de forma til desde el principio. Si se observa la
lnea de ayuda de la gura 3.1 podemos ver que se puede obtener ayuda mediante la pulsacin
de las teclas <Ctrl>-K-H.
El efecto puede verse en la gura 3.2
En ella podemos observar el panel de ayuda con una serie de combinaciones de teclas para
realizar diversas funciones agrupadas por categoras. Existen varios paneles de ayuda suplemen-
tarios. Pueden verse pulsando repetidamente la combinacin de teclas <Esc> . como puede
observarse en la lnea superior de la pantalla; para volver hacia atrs por la serie de paneles de
ayuda, la combinacin de teclas es <Esc> ,.
La notacin usada en los paneles de ayuda usa el smbolo para indicar la pulsacin de la
tecla <Ctrl>. As por ejemplo, en el grupo de comandos EXIT, puede verse que si necesitamos
salir del editor guardando el archivo que estamos editando, debemos usar KX, lo que signica
que debemos mantener pulsada la tecla <Ctrl> mientras pulsamos sucesivamente las teclas
K y X.
20 3.3. El editor de texto joe
Figura 3.1: Pantalla inicial de joe para un archivo sin nombre y vaco
Figura 3.2: Pantalla inicial de joe con el panel de ayuda visible
3.4. Operaciones bsicas en el sistema de archivos 21
Al pulsar la combinacin de teclas que activa un comando puede que obtengamos ms pe-
ticiones de informacin en la lnea de estado. Por ejemplo, en el caso anterior, si el archivo no
tena nombre, se nos pedir que tecleemos el nombre que deseemos asignarle.
Al menos en la etapa inicial, hasta acostumbrarse al uso de joe, se recomienda mantener en
la pantalla del terminal la informacin de ayuda mientras se edita un archivo.
3.4. Operaciones bsicas en el sistema de archivos
3.4.1. Creacin y eliminacin de archivos y directorios (rm, mkdir,
rmdir)
La creacin de archivos y directorios requiere que el usuario tenga los permisos necesarios, de
modo que un usuario no puede crear, borrar o mover archivos o directorios a cualquier posicin
en la jerarqua del sistema de archivos. Discutiremos este problema en la seccin 3.5. Por el
momento supondremos que todas nuestras operaciones tienen lugar en la parte de la jerarqua
del sistema de archivos que desciende de nuestro directorio home.
Ya hemos visto en la seccin 3.3 una de las formas ms comunes de crear archivos (mediante
un editor de texto), pero los archivos a veces tambin necesitan ser borrados.
Para eliminar archivos, la orden del shell es rm. Su formato es

rm [ opci n ] . . . <nombredearchi vo >. . .


Las opciones ms importantes son
-f Ignorar los nodos que no existan. No preguntar
-i Preguntar antes de eliminar cada nodo. Si no se responde pulsando la tecla y, no se borrar
el nodo
-r Eliminar recursivamente el contenido de los directorios. La opcin se puede escribir tambin
como -R y debe ser manejada con extremo cuidado para no perder archivos valiosos
1
La orden para crear directorios es mkdir. Su formato es

mkdir [ opci n ] . . . <nombrenuevodi r e c t o r i o >. . .


Las opciones ms importantes son
-p Crear un directorio creando a la vez los directorios intermedios del path que no existan
-m<modo> Fijar los permisos del directorio. El formato para <modo> es el mismo que se
usa en la orden chmod (vase la seccin 3.5)
1
Vase ms abajo la orden rmdir especca para borrar directorios
22 3.4. Operaciones bsicas en el sistema de archivos
Por ejemplo

mkdir p pepe/j uan


crear en nuestro directorio de trabajo actual el subdirectorio pepe, y dentro de ste crear el
subdirectorio juan.
Para eliminar un directorio, la orden a usar es rmdir. Su formato es

rmdi r [ opci n ] . . . <nombrededi r e c t o r i o >. . .


La opcin ms importante es
-p Eliminar un directorio eliminando a la vez los directorios antecesores en el path que aparezcan
citados explcitamente
Para poder eliminar un directorio mediante rmdir debe estar vaco (esto es, slo debe
contener las entradas . y ..)
3.4.2. Exploracin del contenido de un directorio (ls)
Una de las operaciones que hay que realizar ms frecuentemente consiste en obtener el
listado de las referencias que se guardan en un directorio, o como diremos por brevedad, listar
el contenido de un directorio. La orden del shell para hacer ese trabajo es ls. Su formato es

l s [ opci n ] . . . [<nombredenodo >] . . .


Salvo que las opciones indiquen otra cosa, ls listar los nombres de los archivos que aparezcan
como objetivos y los contenidos de los directorios por orden alfabtico (si existen). Segn las
opciones que se usen, esa informacin puede estar suplementada por otras. Los nodos cuyos
nombres comienzan por el carcter . son considerados ocultos y no aparecern en los listados
a menos que se use la opcin -a.
Si no se especica ningn objetivo, se listar el directorio de trabajo actual.
Las opciones ms importantes son
-a Listar todos los nodos, incluidos aquellos cuyo nombre comience por el carcter .
-i Imprimir el nmero de nodo-ndice asociado a cada nombre
-l Listar, junto al nombre de cada nodo, sus atributos
-n Como la opcin -l pero identicando al propietario y al grupo del nodo mediante los valores
numricos correspondientes
3.4. Operaciones bsicas en el sistema de archivos 23
Figura 3.3: Pantalla con la informacin de ls en formato largo
-R Listar recursivamente los contenidos de los directorios objetivo
Las opciones pueden agruparse y aparecer en cualquier orden. La opcin -l proporciona una
salida organizada en lneas (una para cada nodo) con la informacin siguiente (ver gura 3.3)
El primer carcter de la lnea indica el tipo de nodo. Un carcter - indica un archivo
regular; un carcter d indica que el nodo es un directorio
Los 9 caracteres siguientes indican los permisos aplicables al nodo. Trataremos de ellos en
la seccin 3.5
Los siguientes caracteres no blancos indican el nmero de enlaces fsicos del nodo (ver la
seccin 3.4.8)
La columna siguiente contiene el login del propietario del nodo
La columna siguiente contiene el identicador del grupo de usuarios del sistema al que
est asociado el nodo (abreviadamente grupo del nodo)
La siguiente columna contiene el tamao del nodo en bytes
Las columnas siguientes contienen la fecha y la hora de la ltima modicacin del nodo
La ltima columna contiene el nombre del nodo
El la gura 3.3 puede apreciarse que aparecen listados los nombres del directorio de trabajo
actual incluidos los nodos ocultos (se ha empleado la opcin -a).
24 3.4. Operaciones bsicas en el sistema de archivos
3.4.3. Copia, movimiento y cambios de nombre (cp, mv)
La orden del shell para copiar archivos es cp. Su formato es

cp [ opci n ] . . . <ori gen >. . . <des t i no >


<origen>. . . indica el (los) nombres de los nodos que deben ser copiados. Si alguno de ellos
es un nombre de directorio, se necesita usar la opcin -r
2
.
<destino> indica el nombre del nodo donde el nodo origen debe ser copiado.
Pueden darse los siguientes casos
1. Si <destino> ya existe y es un nombre de archivo, los nodos origen se copiarn en ese
destino, de modo que el contenido de <destino> ser el del ltimo nodo copiado
2. Si <destino> ya existe y es un nombre de directorio, se copiarn los nodos <origen> en
el directorio de destino conservando sus nombres
3. Si <destino> no existe, se crear un archivo con ese nombre y se copiarn los nodos origen
como en el caso 1
Las opciones ms importantes son
-i Modo interactivo. Preguntar antes de sobreescribir
-r Copiar recursivamente los directorios origen. Se puede utilizar esta opcin con la forma -R
La orden del shell para mover nodos de un directorio a otro o cambiarlos de nombre es mv.
La orden tiene dos formatos

mv [ opci n ] . . . <or i gen> <des t i no >


Pueden darse los siguientes casos
1. Si <destino> no existe (es un nombre no usado) se cambiar el nombre de <origen> para
que pase a ser <destino>
2. Si <destino> existe y es un nombre de directorio, <origen> ser movido al directorio de
destino
3. Si <destino> existe y es un nombre de archivo
a) Si <origen> es tambin un nombre de archivo el archivo <destino> ser eliminado
3
y luego se cambiar el nombre del archivo <origen> como en el caso 1
2
Ver opcin -r ms abajo
3
Ver opciones ms abajo
3.4. Operaciones bsicas en el sistema de archivos 25
b) En otro caso se sealar un error

mv [ opci n ] . . . <or i gen >. . . <di r e c t o r i o >


En esta forma, <directorio> debe ser un directorio existente. Cualquier archivo o directorio
<origen>. . . ser movido al directorio <directorio>.
En ambos formatos puede darse el caso de que haya que eliminar archivos o directorios
existentes. En esas situaciones, la orden pedir por defecto conrmacin para ello si el nodo
correspondiente no tiene permiso de escritura.
Las opciones ms importantes son
-i Modo interactivo. Preguntar antes de sobreescribir
-f No preguntar antes de sobreescribir
3.4.4. Exploracin del contenido de un archivo (cat, head, tail)
La orden cat se usa para concatenar el contenido de varios archivos entre s y enviar el
resultado a la salida estndar. Su formato es

cat [ opci n ] . . . [<archi vo >] . . .


Si en la orden no gura ningn nombre de archivo, se leern caracteres de la entrada estndar.
Si la entrada estndar est asociada al teclado del terminal, el n de archivo se indicar, como en
todos los casos en los que se intente leer un archivo a partir del teclado, pulsando la combinacin
de teclas <Ctrl>-D.
Para explorar parcialmente el contenido de un archivo pueden usarse las rdenes head y
tail. Sus formatos, respectivamente, son

head [ opci n ] . . . [<archi vo >] . . .

t a i l [ opci n ] . . . [<archi vo >] . . .


La orden head imprime en la salida estndar (por defecto) las 10 primeras lneas de los
archivos objetivo. Si hay varios nombres de archivo en la orden, el grupo de lneas de cada uno
ir precedido del nombre del archivo.
La orden tail imprime en la salida estndar (por defecto) las 10 ltimas lneas de los archivos
objetivo. Si hay varios nombres de archivo en la orden, el grupo de lneas de cada uno ir
precedido del nombre del archivo.
Las opciones ms importantes, aplicables a ambas rdenes, son
-c Seguida de un nmero, indica el nmero de caracteres que deben ser escritos de cada archivo
-n Seguida de un nmero, indica el nmero de lneas que deben ser escritas de cada archivo
26 3.4. Operaciones bsicas en el sistema de archivos
3.4.5. Cambios en el contenido de un archivo (tee)
La orden tee tiene por objeto tomar caracteres de la entrada estndar y enviarlos a la salida
estndar y, opcionalmente, a varios archivos. Su formato es

t ee [ opci n ] . . . [<archi vo >] . . .


La opcin ms importante es
-a Aadir la entrada al nal de los archivos. No sobreescribir
3.4.6. Estadsticas sobre el contenido de un archivo (wc)
La orden wc tiene por objeto contar los bytes, las palabras y las lneas de varios archivos.
Su formato es

wc [ opci n ] . . . [<archi vo >] . . .


Si hay ms de un archivo objetivo se imprime una lnea de totales adems de las cuentas
para cada archivo. Si no se indica ningn archivo objetivo, o entre los objetivos aparece el signo
-, las cuentas se realizan sobre la entrada estndar.
Las opciones ms importantes son
-c Contar los bytes de cada archivo objetivo
-l Contar los caracteres de nueva lnea de cada archivo objetivo
-w Contar las palabras de cada archivo objetivo
3.4.7. Actualizacin de los atributos de fecha y hora de un archivo
(touch)
La orden touch permite cambiar por defecto a la fecha y hora actual (ver opcin -t) los
atributos de fecha y hora de uno o varios archivos. Su formato es

touch [ opci n ] . . . <archi vo >. . .


Si alguno de los archivos no existe, se crea por defecto (ver opcin -c) con tamao igual a 0.
Las opciones ms importantes son
-a Cambiar la fecha y hora de acceso
-c No crear ningn archivo nuevo
-m Cambiar la fecha y hora de modicacin
-t Seguida de una fecha y hora con formato [[CC]YY]MMDDhhmm[.ss] cambia los atributos de
fecha y hora de los objetivos a la fecha y hora indicada en vez de la actual
3.4. Operaciones bsicas en el sistema de archivos 27
3.4.8. Enlaces (ln)
A diferencia de lo que ocurre con otros sistemas de archivos, los sistemas nativos UNIX
permiten que un mismo nodo est referenciado varias veces en el mismo o distintos directorios,
o como diremos por brevedad, tenga varios nombres.
As pues, un nodo debe tener al menos un nombre, pero puede tener ms de uno. Ello implica
que tanto sus atributos, como el contenido de ese nodo pueden alcanzarse usando cualquiera de
los nombres que tenga.
Por esa razn, a los nombres de los nodos se les denomina en UNIX enlaces. En esta seccin
trataremos la orden del shell que permite crear enlaces. Esa orden es ln. Sus tres formatos ms
usados son

l n [ opci n ] . . . <obj et i vo > <nombreenl ace >


En este caso se crear un nuevo enlace denominado <nombre-enlace> asociado al mismo
contenido y atributos que <objetivo>.

l n [ opci n ] . . . <obj et i vo >


En este caso se crear en el directorio de trabajo actual un enlace con el mismo nombre que
<objetivo>.

l n [ opci n ] . . . <obj et i vo >. . . <di r e c t o r i o >


En este caso se crearn enlaces para los distintos nodos <objetivo> con los mismos nombres
en el directorio <directorio>.
En UNIX pueden crearse dos tipos de enlaces, denominados respectivamente enlaces fsicos
(duros) y enlaces simblicos (blandos). Por defecto, ln crea enlaces fsicos
4
.
Cuando se crea un archivo o un directorio, el enlace correspondiente es un enlace fsico.
Nuevos enlaces fsicos pueden ser creados solamente para los archivos. Cualquier nuevo enlace
fsico que se cree para un archivo puede usarse de modo equivalente a como se usa el nombre
original.
Lo anterior plantea el problema de qu sucede con los enlaces fsicos de los archivos cuando
borramos un archivo. Lo que sucede en realidad es que se borra la referencia al archivo en el
directorio correspondiente a ese enlace, de modo que ese nombre en ese directorio no estar ya
asociado al archivo. Todos los dems enlaces fsicos que el archivo tenga podrn seguir usndose
como antes. El sistema de archivos lleva una cuenta de los enlaces fsicos que tiene cada archivo
(en la seccin 3.4.2 puede verse esa informacin en los listados que proporciona la orden ls con
la opcin -l), y cuando, al borrar un enlace, el sistema detecta que es el ltimo enlace fsico de
4
Para crear enlaces simblicos vase ms abajo la opcin -s
28 3.5. Permisos en el sistema de archivos
ese archivo, entonces borra el contenido del archivo (esto es, declara libre el sitio que ocupa en
el almacenamiento).
Los enlaces simblicos tienen otro comportamiento. Pueden crearse tanto para archivos como
para directorios. En los listados proporcionados por la orden ls, los enlaces simblicos aparecen
con el formato
<enlace-simblico> -> <enlace>
donde <enlace> es otro enlace existente previamente (fsico o simblico) que fue el usado para
crear <enlace-simblico>. Adems, el carcter que, en los listados largos de la orden ls (opcin
-l), se usa para identicar el tipo de nodo (el primero de cada lnea), en el caso de los enlaces
simblicos es el carcter l.
La diferencia esencial entre los enlaces simblicos y los fsicos es que con los enlaces simblicos,
el acceso a los atributos y a la informacin del nodo se logra recorriendo la cadena de posibles
enlaces simblicos hasta que se encuentra un enlace fsico, lo cual permite el acceso a los datos.
Pero cuando se borra el enlace fsico nal de la cadena o cualquiera de los enlaces simblicos
intermedios, el enlace simblico inicial, y todos los anteriores al punto de rotura en la cadena
no se eliminan y se vuelven entonces enlaces denominados colgantes (esto es, no apuntan a
ninguna parte). Cuando luego intentamos usar un enlace colgante, el sistema de archivos no
puede encontrar el contenido o los atributos del nodo mediante ese nombre, y seala un error.
Por otra parte, los enlaces simblicos, al poder realizarse entre directorios, pueden dar lugar
a ciclos en el grafo del sistema de archivo, lo cual puede degradar el rendimiento de determinadas
bsquedas.
Las opciones ms importantes son
-f Si el nombre del enlace que debe crearse ya existe, borrar el nodo previamente existente y
crear luego el enlace
-s Crear un enlace simblico
3.5. Permisos en el sistema de archivos
Como hemos comentado en la seccin 3.4.2 y observado en la gura 3.3, los archivos y
directorios (en general todos los nodos del sistema de archivos) tienen un propietario, estn
asociados a un grupo de usuarios (grupo del nodo) y tienen unos permisos de uso.
En esta seccin revisaremos las rdenes del shell que permiten cambiar esos atributos para
un nodo determinado.
3.5.1. Cambios de propietario y grupo (chown, chgrp)
Las rdenes para cambiar el propietario y el grupo de un nodo son respectivamente chown
y chgrp. Sus formatos son

chown [ opci n ] . . . [<usuari o >] [ : [ <grupo >] ] <nodo >. . .


3.5. Permisos en el sistema de archivos 29

chgrp [ opci n ] . . . <grupo> <nodo >. . .


En chown <usuario> indica el nuevo propietario para los nodos objetivo.
En las dos rdenes <grupo> indica el nuevo grupo para los nodos objetivo.
Tanto <usuario> como <grupo> pueden darse mediante los nombres o mediante los nmeros
correspondientes.
En chown, si se especican <usuario> y <grupo> se cambiarn el propietario y el grupo de
los nodos. Si slo se especica <usuario> slo se cambiar el propietario, y si slo se especica
<grupo> (precedido del carcter :) slo se cambiar el grupo (el funcionamiento en este caso
es idntico al de chgrp). Si no se especica ninguno de los dos datos no se realizar ningn
cambio.
Para ejecutar cualquiera de las dos rdenes es necesario estar operando en el terminal como
superusuario (root).
La opcin ms importantes para ambas rdenes es
-R Operar en archivos y directorios recursivamente
3.5.2. Cambios de permisos (chmod)
Para el manejo de los permisos de un nodo, UNIX distingue tres tipos de usuarios: el pro-
pietario del nodo, los usuarios del grupo del nodo y el resto de los usuarios del sistema.
Para cada nodo, UNIX almacena los permisos aplicables a cada uno de los tres tipos de
usuarios. Para cada tipo, UNIX almacena si ese tipo de usuarios tiene permiso de lectura, si
tiene permiso de escritura y si tiene permiso de ejecucin. En cada caso el permiso puede estar
concedido o no. Hay, por tanto, tres permisos para cada tipo de usuario, lo que hace en total 9
permisos que pueden estar concedidos o no.
Para cualquier operacin en la que se necesite manipular un nodo, el sistema de archivos
controla si se tiene permiso para hacerla o no a partir del identicador del usuario que pretende
hacer la operacin.
El algoritmo usado es el siguiente: Si el usuario que pretende hacer la operacin es el propie-
tario del nodo, se le aplicarn los permisos del propietario; si no, si el usuario pertenece al grupo
de usuarios del nodo, se le aplican los permisos del grupo. Si no, se le aplican los permisos del
resto de los usuarios.
Como ya hemos visto en la gura 3.3, esos permisos para cada nodo estn descritos por los
9 caracteres que siguen al primero en la lnea del informe que corresponde a cada nodo. La
notacin utilizada es la siguiente: los tres primeros caracteres son los permisos del propietario,
los tres siguientes los permisos del grupo y los tres restantes los permisos de los dems usuarios.
En cada caso los tres permisos de cada tipo de usuarios estn ordenados de la misma forma:
lectura, escritura y ejecucin. Si hay permiso de lectura habr una r, si hay permiso de escritura
habr una w, si hay permiso de ejecucin habr una x. Si cualquiera de los permisos no est
concedido, en su lugar habr un carcter -.
Por ejemplo
30 3.5. Permisos en el sistema de archivos
rw-r-x-w-
indica permisos de un nodo en el que el propietario tiene permiso de lectura y escritura, pero
no de ejecucin; los usuarios del grupo del nodo tienen permisos de lectura y de ejecucin, pero
no de escritura; el resto de los usuarios tiene permiso de escritura, pero no de lectura ni de
ejecucin.
El signicado de los permisos diere un poco en el caso de los archivos y en el caso de los
directorios.
Tener permiso de lectura en un archivo signica que se puede leer su contenido.
Tener permiso de escritura en un archivo signica que su contenido puede ser cambiado.
Tener permiso de ejecucin en un archivo signica que, si el archivo contiene un programa
ejecutable o una macro del shell (el texto de un programa interpretable por el shell), podr
pedirse al shell que intente ejecutar el programa correspondiente. Recurdese que los nombres
de los archivos no tienen en UNIX ningn signicado especial. La forma en que UNIX distingue
los archivos que (en principio) contienen programas es mediante los permisos de ejecucin que
tenga el archivo.
Tener permiso de lectura en un directorio signica que podemos explorar su contenido (por
ejemplo podemos listar su contenido mediante ls).
Tener permiso de escritura en un directorio signica que podemos cambiar las entradas del
directorio. Por ejemplo si queremos crear un archivo necesitamos permiso de escritura en el
directorio donde vayamos a hacerlo para poder crear la entrada. Lo mismo sucede si queremos
borrar un archivo o cambiar sus permisos, etc.
Tener permiso de ejecucin en un directorio signica que podemos atravesar ese directorio
para buscar un archivo o un directorio en l. As pues, para acceder a un archivo, necesitamos
tener permiso de ejecucin en todos los directorios del path que usemos en el nombre completo
del archivo, adems de los permisos de acceso al archivo mismo, que dependern de lo que
necesitemos hacer con l. Otro caso en el que necesitamos permiso de ejecucin en un directorio
es cuando necesitamos convertirlo en nuestro directorio de trabajo actual (mediante la orden
cd).
Una aplicacin, cuando crea un nodo, le asigna unos permisos, y el propietario y el grupo
del nodo quedan asignados como el login y el identicador de grupo del usuario que ejecuta la
aplicacin.
Posteriormente, el propietario del nodo y slo l, aparte del superusuario, puede cambiar los
permisos del nodo.
La orden del shell para cambiar esos permisos es chmod. Su formato bsico es

chmod [ opci n ] . . . <nuevomodo> <nodo >. . .


<nuevo-modo>es un nmero de entre una y cuatro cifras octales. Las cifras que no guren
se considerarn ceros a la izquierda.
Nosotros, en esta introduccin slo usaremos las tres ltimas cifras octales; la de ms a la
izquierda la consideraremos cero. Esa cifra se utiliza para usos especiales que no discutiremos
aqu.
3.5. Permisos en el sistema de archivos 31
Como tres cifras octales corresponden a nmeros de 9 bits, que son el nmero de permisos
que tenemos que manejar, formaremos el nmero <nuevo-modo> de modo que tenga un bit 1 en
el lugar correspondiente a un permiso que est concedido, y un bit 0 en el lugar correspondiente
a un permiso no concedido. La ordenacin de los bits deber ser la misma que hemos descrito
antes.
Por ejemplo si queremos que los nuevos permisos sean
r--rwx-w-
<nuevo-modo> deber ser 472, puesto que ese nmero octal, en binario, se escribira 100111010.
La orden chmod cambiar los permisos (modo) de los nodos objetivo a <nuevo-modo>.
Los permisos de los enlaces simblicos no pueden ser cambiados mediante chmod. En reali-
dad esos permisos se asignan siempre de la misma forma por el sistema de archivos y son
inmutables. Cuando se usa chmod con un enlace simblico como objetivo, en realidad, el cam-
bio de permisos afecta al nodo apuntado por la cadena de enlaces que comienza en el enlace
simblico (si es que el nodo existe).
La orden chmod admite otro formato

chmod [ opci n ] . . . <modo>[,<modo >] . . . <nodo >. . .


Con este formato se usan las letras u, g, o para indicar a qu tipo de usuarios se reeren
los nuevos permisos (u para el propietario, g para el grupo de usuarios del nodo y o para el
resto de los usuarios). Se usan los signos =, +, - para indicar si los nuevos permisos deben
aadirse a los actuales (+), deben retirarse de los actuales (-) o deben ser exactamente los
que se indican (=). Se usan las letras r, w, x para referirse a permisos de lectura (r), de
escritura (w), y de ejecucin (x).
Si hay que asignar distintos permisos a diferentes tipos de usuarios, se pueden encadenar las
expresiones simblicas mediante el carcter ,.
Por ejemplo
ug+rw,o=rx
indicara que el nuevo modo aplicable a los nodos objetivo debera aadir (+) permisos de
lectura y escritura (rw) a los permisos que tenga cada nodo para el propietario y para el grupo
del nodo (ug), mientras que se desea que, en cada nodo, los permisos del resto de los usuarios
(o) sean exclusivamente de lectura y ejecucin (rx), con independencia de los que tuvieran
previamente (=).
La opcin ms importante es
-R Operar en archivos y directorios recursivamente
Captulo 4
Operaciones especiales asociadas a
las rdenes del shell
4.1. Variables de shell (set, export, echo)
Como cualquier otro intrprete, el shell admite la denicin de variables. Las variables del
shell tienen nombres que se escriben convencionalmente en letras maysculas.
Uno de los usos ms corrientes de las variables del shell consiste en describir valores que
deben ser usados en el entorno de ejecucin de ciertas rdenes (vase 4.1.1). Al abrir una sesin
del shell, el usuario dispone de un entorno con una serie de variables ya denidas. Entre ellas,
algunas de las ms importantes son PATH, BASH, HISTSIZE, HISTFILESIZE, HISTFILE,
HOME, HOSTNAME, LANG, USER, UID.
La orden set permite manipular los valores de las variables ya denidas. Su formato es

s e t [ opci ones ] [o <nombreopci n >] [<argumento >. . . ]


Cuando set se usa sin opciones ni argumentos, permite obtener un listado de todas las
variables del shell denidas junto con sus correspondientes valores.
La orden export sirve para denir una variable que ser pasada a los procesos hijos del shell
formando parte de su entorno. Su formato es

export [ opci ones ] [<nombre>[=<val or >] ]


<nombre> es el nombre de la variable, mientras <valor> es corrientemente una nica palabra
(tpicamente un nmero entero) o bien una cadena de caracteres entre comillas dobles si la cadena
contiene caracteres blancos.
La orden echo sirve para imprimir un mensaje en la salida estndar. Su formato es
33
34 4.2. Redireccin de la entrada, la salida y la salida de error estndares

echo [ opci n ] . . . [<cadena >] . . .


<cadena> es la cadena de caracteres que desea enviarse a la salida. Si la cadena de caracteres
es de la forma $<nombre_de_variable> lo que se enviar a la salida es el valor de la variable.
4.1.1. El entorno de una orden (env)
Cuando el shell genera un proceso hijo para ejecutar una orden, por defecto le pasa como
variables de entorno todas las que l tenga denidas.
No obstante, si se quieren jar explcitamente las variables de entorno que una orden debe
usar, se puede usar la orden env para ejecutar la orden del shell deseada. El formato de la orden
env es

env [ opci n ] . . . [<nombre>=<val or >] . . . [<Comando> [<argumento >] . . . ]


4.1.2. Path de los ejecutables del shell (which)
La orden which permite obtener el path de un archivo ejecutable si se conoce su nombre. La
bsqueda recorre el sistema de archivo buscando en los directorios citados en la variable PATH,
por orden, y por defecto (ver opcin -a) se detiene en cuanto encuentra el nombre del ejecutable
por primera vez. El formato de la orden es

which [ opci ones ] [] <nombre_de_programa >. . .


which permite por tanto encontrar un ejecutable que resida en uno de los directorios citados
en la variable PATH, y en particular cualquiera de las rdenes del shell.
La opcin ms importante es
-a Imprimir todos los path del ejecutable que se encuentren en los directorios citados en la
variable de entorno PATH, y no slo el primero
4.2. Redireccin de la entrada, la salida y la salida de error
estndares
Muchas rdenes del shell usan como dispositivo de entrada el que est denido como entrada
estndar. Comunmente ese dispositivo es el teclado del terminal, pero el shell permite que una
orden use como dispositivo de entrada estndar un archivo. El modo de hacerlo consiste en
aadir a la orden tal como se escribira normalmente el nombre del archivo del que queremos
que se obtengan los caracteres de entrada precedido del operador < (puede haber espacios de
separacin entre ambos). Por ejemplo
4.3. Agrupacin y encadenamiento de rdenes 35

cat < entrada


tomara los caracteres del archivo cuyo nombre es entrada y los enviara a la salida estndar
(tpicamente la pantalla del terminal).
La operacin anterior se denomina redireccin de la entrada estndar.
Es posible tambin redirigir la salida estndar. La forma de conseguirlo es anloga a la
anterior, pero el operador es el signo >. Por ejemplo

cat uno dos > s a l i da


enviara la concatenacin de los contenidos de los archivos uno y dos a la salida estndar, pero
sta no sera la pantalla del terminal sino un archivo llamado salida. Si el archivo existe, su
contenido previo se pierde.
Si se usa el operador >> para la redireccin de la salida, sta se enva al archivo de destino,
pero se aade al nal de l (el archivo no se sobreescribe).
Tambin se puede redirigir la salida de error estndar de la misma forma, salvo que el
operador correspondiente es 2>.
Se pueden usar los operadores anteriores en la forma <$<dgito>, >$<dgito>, donde <d-
gito> es un descriptor de archivo abierto, tpicamente el de la entrada estndar, el de la salida
estndar o el de la salida de error estndar. Los descriptores de la entrada estndar, la salida
estndar y la salida de error estndar son respectivamente 0, 1 y 2.
4.3. Agrupacin y encadenamiento de rdenes
Ante el indicador (prompt) del shell podemos escribir una orden tal como lo hemos he-
cho hasta ahora, pero tambin es posible escribir varias, separadas por uno de los separadores
siguientes: ;, && y ||.
Las rdenes agrupadas de esa forma se ejecutarn una tras otra incondicionalmente si estn
separadas por el separador ;.
El separador && ejecuta la orden siguiente slo si la anterior devuelve 0 como estado de
salida (xito). En caso contrario, el resto de las rdenes parciales no se ejecutan.
El separador || ejecuta la orden siguiente slo si la anterior devuelve un valor distinto de
0 como estado de salida (fracaso). En caso contrario, el resto de las rdenes parciales no se
ejecutan.
Otra operacin posible con las rdenes es el encadenamiento. Se puede usar la salida de una
orden (<orden_1>) como entrada de otra (<orden_2>), y la salida de sta como entrada de
otra, etc. La forma de hacerlo es conectar las rdenes parciales mediante el operador | de la
forma siguiente

<orden_1> | <orden_2> | . . .
36 4.4. Creacin de shells hijos (sh)
Por ejemplo

l s al | wc l
escribir en la salida estndar el nmero de lneas del informe que producira la orden ls.
El operador | se llama operador pipe. Se pueden agrupar pipes de la misma forma que las
rdenes simples.
4.3.1. Ejecucin en segundo plano
Hasta ahora hemos ejecutado rdenes de modo que hay que esperar a que termine la ejecucin
de la orden antes de que el shell nos permita escribir y pedir la ejecucin de otra.
Esa forma de trabajar se denomina ejecucin en primer plano.
A veces, sin embargo, nos interesa poder ejecutar una orden, y, sin esperar a que termine,
pedir al shell que ejecute otra. Para ello, la primera orden debe ser seguida del operador &, lo
que indicar al shell que deseamos ejecutarla en segundo plano, concurrentemente (UNIX es un
sistema multiprogramado) con otras que escribiremos luego.
Cuando hacemos eso, el shell imprime un nmero que es el identicador de proceso de la
orden en segundo plano y vuelve inmediatamente a escribir el prompt para permitirnos escribir
nuevas rdenes (que pueden ejecutarse en primer plano o tambin, si queremos, en segundo
plano).
Es corriente redirigir los descriptores de la entrada, la salida y la salida de error estndares
de las rdenes que se ejecutan en segundo plano para evitar que lean o escriban en los mismos
dispositivos que estemos usando para las rdenes que ejecutemos en primer plano.
Por ejemplo, si escribimos
_
`

which wc > s a l i da &


l s al
se ejecutar la orden which en segundo plano, enviando su salida al archivo salida. Inmedia-
tamente de comenzar la ejecucin de which podemos escribir la orden ls y obtener su listado
de salida. En l, y puesto que la ejecucin de which es muy corta, es posible que ya gure el
archivo salida, producido por which, por lo que podra obtenerse la salida de la gura 4.1, que
indica el identicador de proceso de la orden which (en el ejemplo 1152) y, ms tarde, que la
orden which ha terminado su ejecucin.
4.4. Creacin de shells hijos (sh)
A veces es necesario crear en el shell un proceso hijo que ejecute otro shell (subshell), para
poder ejecutar en l ordenes distintas de las que queramos ejecutar en el shell de partida. La
orden para crear un subshell es sh. Su formato es
4.4. Creacin de shells hijos (sh) 37
Figura 4.1: Ejemplo de ejecucin en segundo plano

sh
La orden sh crea un nuevo proceso que ejecuta otro shell, sobre el que podremos ejecutar
rdenes o macros del shell y del que podremos salir al terminar mediante la orden exit como
habitualmente.
Captulo 5
Otras rdenes tiles
5.1. Bsqueda de informacin en el sistema de archivos
Dada la gran cantidad de informacin que est almacenada habitualmente en cualquier
sistema de archivos, uno de los problemas ms frecuentes que se plantea al usuario del sistema
es localizar los archivos que le interesan.
Distinguiremos dos tipos genricos de bsquedas: aquellas en las que se intenta localizar
el o los archivos que nos interesan a partir de condiciones sobre su nombre u otros atributos
y aquellas otras en las que queremos localizar las lneas de los archivos que contienen (en su
interior) determinadas cadenas de caracteres.
5.1.1. Bsqueda de archivos por sus atributos (nd, locate)
La orden nd
La orden nd se usa para localizar archivos particulares y posiblemente ejecutar algn tipo
de accin sobre ellos. Esta orden busca, explorando recursivamente uno o varios directorios,
los nodos que cumplan las condiciones expresadas en la orden y les aplica las acciones que se
indiquen.
A lo largo de la ejecucin de la orden nd, se va tratando cada nodo de los directorios
afectados (nodo objetivo) de modo que se comprueba si se cumplen las condiciones expresadas
para aplicar o no las acciones correspondientes.
En GNU, el formato de la orden es

f i nd [H] [L] [P] [<path >. . . ] [<expr es i n >]


Las opciones -H, -L y -P regulan el comportamiento de la orden en el tratamiento de los
enlaces simblicos
1
. De esas opciones slo se usar la ltima que aparezca. Si no gura ninguna
1
Para los detalles se recomienda la consulta de la pgina de manual de nd
39
40 5.1. Bsqueda de informacin en el sistema de archivos
opcin, por defecto se usar -P, lo que signica que los enlaces simblicos no se seguirn, y la
aplicacin de las condiciones se realizar sobre el propio enlace simblico.
<path> es el nombre de un path de bsqueda en el que debe realizarse la exploracin
recursiva. Si no se especica ninguno, se tomar el nombre del directorio de trabajo actual. La
lista de posibles paths de bsqueda termina en cuanto aparezca un argumento que comience por
el signo -.
<expresin> es un argumento formado por opciones, tests y acciones interconectadas por
operadores lgicos. Las distintas partes de la expresin son evaluadas como operandos lgicos,
siguiendo las reglas de precedencia de los operadores, y evaluando los operandos del mismo
operador de izquierda a derecha. La evaluacin de la expresin termina en cuanto se conozca
su resultado lgico (en cuanto el operando izquierdo de un AND lgico sea falso o cuando el
operando izquierdo de un OR lgico sea cierto). A continuacin se contina con el tratamiento
del siguiente nodo objetivo.
Si no gura ninguna expresin en la orden se tomar por defecto -print.
Opciones: Todas ellas retornan el valor true. Salvo -follow y -daystart
2
, las dems tie-
nen efecto para todos los nodos objetivo, independientemente de dnde aparezcan escritas las
opciones en la expresin. Por ello se colocan generalmente, por claridad, al principio de ella. Las
opciones ms importantes son
-maxdepth Seguida de un entero no negativo n, indica descender recursivamente como mximo
n niveles por debajo del path de bsqueda que gura en la orden. Si n es 0 slo se aplicar
la expresin a los paths de bsqueda de la orden (sin hacer un recorrido recursivo)
-mindepth Seguida de un entero no negativo n, indica que no se debe aplicar ningn test ni
accin a los nodos situados a menos de n niveles por debajo del path de bsqueda que
gura en la orden. Si n=1 se tratarn todos los nodos que estn por debajo estrictamente
de los paths de bsqueda de la orden
Tests: Son condiciones que deben ser comprobadas sobre cada nodo objetivo. Su resultado
ser true o false segn se cumpla la condicin o no. En ellos pueden gurar argumentos numricos
en las siguientes formas
+n Su signicado es un nmero mayor que n
-n Su signicado es un nmero menor que n
n Su signicado es exactamente n
Los tests ms importantes que suelen usarse son
-gid Seguido de un entero n, comprueba si el grupo del nodo objetivo tiene el identicador
numrico n
-group Seguido de un nombre, comprueba si el grupo del nodo objetivo tiene ese identicador.
Se permite tambin un identicador numrico
2
Para ms detalles vase la pgina de manual de nd
5.1. Bsqueda de informacin en el sistema de archivos 41
-inum Seguido de un entero n, comprueba si el inodo del nodo objetivo tiene el valor numrico
n
-links Seguido de un entero n, comprueba si el nmero de enlaces del nodo objetivo tiene el
valor numrico n
-name Seguido de un nombre, comprueba si el nombre del nodo objetivo coincide con ste. Si
el nombre incluye metacaracteres (ver seccin 3.2) es necesario encerrarlo entre apstrofos
para evitar la expansin por el shell
-perm Seguido de un modo expresado en octal o de forma simblica (vase la seccin 3.5.2),
comprueba si el modo del nodo objetivo es el indicado
-size Seguido de un entero n, comprueba si el tamao del nodo objetivo tiene el valor numrico
n. Por defecto el tamao se mide en bloques de 512 bytes pero se puede cambiar la unidad
aadiendo sujos al valor de n. El caso ms importante es el del sujo c para que n
se interprete como tamao medido en caracteres. Otros sujos posibles son k (para
especicar kilobytes), M (para especicar megabytes) y G (para especicar gigabytes)
-type Seguido de un descriptor de tipo, comprueba si el tipo del nodo objetivo es el correspon-
diente al descriptor. Los descriptores de tipo ms importantes son
f Archivo regular
d Directorio
l Enlace simblico
b Dispositivo de bloques
c Dispositivo de caracteres
-uid Seguido de un entero n, comprueba si el propietario del nodo objetivo tiene el identicador
numrico n
-user Seguido de un nombre, comprueba si el propietario del nodo objetivo tiene ese identi-
cador. Se permite tambin un identicador numrico
Acciones: Son los elementos de la expresin que en la orden nd indican qu debe hacerse
con un nodo objetivo cuando la evaluacin de la expresin hasta el momento en que se alcanza
la accin toma el valor true. Se pueden incluso ejecutar otras rdenes del shell en ese caso
3
, pero
las acciones ms corrientes son
-delete Se usa para borrar el nodo objetivo. Su resultado es true si el borrado tiene xito y
false caso contrario
-print Se usa para imprimir en la salida estndar el nombre completo del nodo objetivo seguido
de un carcter de nueva lnea. Su resultado es true
-printf Seguida de una cadena de formato, se usa para imprimir en la salida estndar los valores
de diferentes atributos del nodo objetivo con un formato determinado. Su resultado es
true. La cadena de formato especica los atributos a imprimir, su orden y el formato
correspondiente de modo parecido a como funciona la funcin printf de la biblioteca
3
Consltese en la pgina de manual de nd el uso de la accin -exec y otras anlogas
42 5.1. Bsqueda de informacin en el sistema de archivos
estndar C. A diferencia de -print, -printf no aade al nal de su salida un carcter de
nueva lnea a no ser que la cadena de formato lo especique. Para ms informacin sobre
la construccin de la cadena de formato y la sintaxis de los grupos de sustitucin vase la
pgina de manual de la orden nd. Esta accin no es conforme al estndar POSIX
-ls Su resultado es true. Se usa para imprimir en la salida estndar los atributos del nodo
objetivo en el mismo formato que lo hara la orden ls con las opciones -dils. Esta accin
no es conforme al estndar POSIX
Si en una expresin no hay acciones distintas de la accin -prune
4
la accin tomada por
defecto cuando la expresin resulta true para el nodo objetivo es -print.
Operadores lgicos: Las diferentes partes de una expresin pueden aparecer conectadas
mediante operadores lgicos. La evaluacin sigue normas de prioridad para los distintos opera-
dores, pero el orden de evaluacin puede ser alterado mediante el uso de parntesis. Cuando se
usan parntesis deben escribirse como \( y \) para evitar su interpretacin especial por el
shell. Los operadores lgicos por orden de prioridad decreciente son
! Su forma es !expr. El valor es true si expr es false y viceversa
-a Su forma es expr1 -a expr2. El valor es true si ambas expr1 y expr2 son true, y false en
otro caso. Si expr1 es false, expr2 no se evala. Si entre dos expresiones no aparece ningn
operador se presupone -a
-o Su forma es expr1 -o expr2. El valor es true si alguna de las expresiones expr1 o expr2 o
ambas son true, y false en otro caso. Si expr1 es true, expr2 no se evala
En la forma GNU de nd puede formarse una lista de subexpresiones separndolas mediante
el carcter ,. En ese caso las subexpresiones se evalan todas, de izquierda a derecha y el valor
de la expresin completa es el de la ltima subexpresin. Como operador, la coma es el de menor
prioridad. Este operador no es conforme al estndar POSIX.
Ejemplos:

f i nd / et c s i z e +20 pr i nt
busca los archivos de un tamao mayor de 20 bloques de 512 bytes por debajo del directorio
/etc e imprime sus nombres completos.

f i nd $HOME \( name . [ c f ] o name . ol d \) type f l s


busca recursivamente en el directorio HOME del usuario los nodos con nombres que terminen
en .c, .f o .old y que adems sean archivos regulares, e imprime en la salida estndar la
informacin de directorio correspondiente en formato largo.
4
Para ms detalles vase la pgina de manual de la orden nd
5.1. Bsqueda de informacin en el sistema de archivos 43
La orden locate
La orden locate permite a un usuario buscar en una base de datos indexada los archivos cuyo
nombre contiene una determinada cadena de caracteres. Sus dos formas bsicas ms corrientes
son

l o c at e u [o <nombrebasedatos >]

l o c at e [database=<path >] <cadenabsqueda>


La primera forma se usa para crear una base de datos o actualizarla. Slo el administrador
del sistema puede crear la base de datos por defecto y omitir la opcin -o y el <nombre-base-
datos>. La base de datos creada contendr informacin de todos los archivos del sistema de
archivos, puesto que se construye a partir del directorio raz. Para otras opciones consltese la
pgina de manual de locate.
La segunda forma busca en la base de datos que se especique, o en la base de datos por
defecto en caso contrario, los nodos del sistema de archivo que contengan en su nombre <cadena-
bsqueda>.
5.1.2. Bsqueda de archivos por su contenido (grep)
La orden grep obtiene las lneas que responden a un patrn en uno o varios archivos. Su
formato es

grep [ opci ones ] <patrn> [<nombrearchi vo >. . . ]


grep busca en los archivos cuyos nombres se citan en la orden, o en la entrada estndar si
en la orden no aparece ningn nombre de archivo, las lneas que corresponden a un patrn y,
por defecto, las imprime en la salida estndar.
<patrn> es una expresin regular construida anlogamente a las expresiones aritmticas
mediante el uso de diferentes operadores para combinar expresiones ms simples. Las expresiones
regulares ms simples son los caracteres. Todas las letras y cifras son expresiones regulares que
concuerdan consigo mismas. Para una informacin detallada sobre la sintaxis de las expresiones
regulares admitidas por grep vase la pgina de manual correspondiente.
Las opciones ms importantes son
-c Suprimir la salida normal y en vez de ella imprimir el nmero de lneas coincidentes en cada
archivo
-n Aadir a cada lnea coincidente un prejo con el nmero de lnea que le corresponde dentro
del archivo en el que aparece
-r Leer todos los archivos por debajo de cada directorio recursivamente. La opcin se puede
escribir tambin en la forma -R
-H Imprimir el nombre del archivo para cada coincidencia
44 5.2. Manipulacin de archivos
5.2. Manipulacin de archivos
5.2.1. Compresin de archivos (gzip)
La orden gzip permite comprimir (y opcionalmente descomprimir) archivos usando una
codicacin LZ77. Su formato es

gzi p [ opci ones ] [<nombrearchi vo >. . . ]


Si no se indica ningn <nombre-archivo> o si <nombre-archivo> es el carcter -, la entrada
se tomar de la entrada estndar y la salida se enviar a la salida estndar. En cualquier caso,
gzip slo comprimir archivos regulares, y en particular ignorar los enlaces simblicos. Por
defecto, si se especica algn <nombre-archivo>, gzip crear un archivo con el nombre formado
a partir del nombre del archivo original, aadindole los caracteres .gz
Las opciones ms importantes son
-c Enviar la salida a la salida estndar
-d Descomprimir uno o varios archivos comprimidos
-f Forzar la compresin o descompresin incluso si el archivo tiene varios enlaces o el archivo
de salida ya existe
-r Recursivo. Si cualquiera de los nombres que aparecen en la orden es un nombre de directorio,
se recorrer ste recursivamente comprimiendo, o en su caso descomprimiendo, los archivos
que encuentre
Es conveniente revisar la forma de la orden gunzip para descomprimir archivos en la misma
pgina de manual de gzip.
5.2.2. Serializacin de archivos (tar)
La orden tar permite serializar archivos o directorios creando un archivo nico (archivo tar)
que puede ser deserializado en cualquier momento para regenerar los archivos o la estructura de
directorio originales. Su formato es

t ar [ opci ones ] [<nombrearchi vo >. . . ] [<nombreded i r e c t o r i o . . . >]


El archivo tar correspondiente es enviado por defecto a la salida estndar. Las opciones ms
importantes son
c Crear un archivo tar
f Seguida de un nombre de archivo, causar que se cree un archivo tar con ese nombre en vez
de enviar la salida a la salida estndar
5.2. Manipulacin de archivos 45
r Permite aadir archivos a un archivo tar
t Listar el contenido de un archivo tar
x Extraer el contenido de un archivo tar (deserializarlo)
u Aadir a un archivo tar los archivos que se indican slo si son ms modernos que los contenidos
en el archivo tar
v Listar los archivos procesados
z Comprimir el archivo tar mediante gzip
De entre las opciones anteriores debe usarse una sola entre las c, r, t, x, u.
5.2.3. Ordenacin de lneas en archivos (sort)
La orden sort permite ordenar las lneas de varios archivos. Su formato es el siguiente

s or t [ opci n ] . . . [<nombrearchi vo >. . . ]


Se ordenan los diferentes archivos de acuerdo con las opciones indicadas y se enva la conca-
tenacin de los resultados a la salida estndar. Si no gura ningn <nombre-archivo> se toma
la entrada de la entrada estndar. Salvo que las opciones indiquen lo contrario, el criterio de
ordenacin corresponde al del cdigo utilizado para representar los caracteres. Las opciones ms
importantes son las siguientes
-b Ignorar los caracteres blancos a la izquierda de los campos
-f Ignorar la diferencia entre maysculas y minsculas y ordenar como si todo fueran maysculas
-n Ordenar usando para los nmeros su valor, no por caracteres. As, con la opcin -n, 1234 es
posterior a 32, pero sin la opcin -n el orden es el contrario
-r Orden inverso. Ordenar de mayor a menor
-k Seguido de una especicacin de claves (ver ms abajo) se usa para ordenar las lneas del
archivo por distintos campos
La especicacin de claves de ordenacin es de la forma POS1[,POS2], donde POS1 indica
la posicin en la que comienza la clave de ordenacin y POS2 la posicin en la que termina la
clave de ordenacin. Si POS2 no existe, el n de la clave es el n de lnea. Si no se usa la opcin
-k, la clave de ordenacin es la lnea completa.
El formato de POS1 (y de POS2) es F[.C][<opciones>]. F es el nmero de campo (los
campos son series de caracteres separadas por caracteres blancos o tabuladores) mientras C
es el nmero de carcter dentro del campo.
Las <opciones> que pueden acompaar la especicacin de la posicin de comienzo o nal
de una clave son letras que indican opciones de ordenacin que se aplican para esa clave en vez
46 5.3. Miscelnea
de las opciones generales especicadas en la orden. Para ms informacin vase la pgina de
manual de sort.
El uso de la opcin -k es propio de la versin GNU de sort. En la mayora de las versiones
de UNIX, sort especica las claves anteponiendo un signo + a la especicacin de la posicin
inicial y un signo - a la de la posicin nal, sin utilizar la coma. No obstante, en esta forma,
la clave comienza en el campo siguiente al especicado y termina en el que se especique. Por
ejemplo

s or t +2 3
ordenar la entrada estndar usando como clave los caracteres del tercer campo de cada lnea.
Pueden especicarse varias claves de ordenacin. En ese caso la ordenacin tiene lugar por la
primera clave que aparezca en la lnea de rdenes, y, para las lneas en las que esa clave resulte
igual, se realizar una ordenacin por la siguiente clave, etc.
5.2.4. Sumas de comprobacin en archivos (md5sum)
La orden md5sum permite generar una suma MD5 (128 bits) tal como se describe en la
RFC 1321 para cada uno de los archivos cuyo nombre aparezca en la lnea de rdenes. Si no se
da ningn nombre de archivo o se usa el carcter - se lee de la entrada estndar.
La orden se utiliza para comparar los contenidos de uno o ms archivos, puesto que dos
archivos de contenidos diferentes tendrn sumas de comprobacin MD5 diferentes. El formato
de la orden es el siguiente

md5sum [ opci ones ] [<nombrearchi vo >. . . ]


Las opciones ms importantes son las siguientes
-b Los archivos se leen en modo binario
-t Los archivos se leen en modo texto (opcin por defecto)
5.3. Miscelnea
5.3.1. Informacin sobre el sistema de archivos (df, du)
La orden df permite obtener en la salida estndar informacin sobre el espacio disponible
en los sistemas de archivos que contienen archivos determinados. Su formato es el siguiente

df [ opci n ] . . . [<nombrearchi vo >. . . ]


5.3. Miscelnea 47
Si no se especica ningn nombre de archivo se proporciona la informacin sobre todos los
sistemas de archivos montados actualmente.
Si el nombre de archivo que se usa corresponde a un dispositivo que contiene un sistema de
archivos, la informacin que se obtiene es la correspondiente a ese sistema de archivos, y no la
del sistema de archivos en el que reside el archivo mismo (tpicamente el sistema de archivos
raz). Las opciones ms importantes son
-h Imprimir los tamaos en formato legible por personas
-i Listar la informacin de i-nodos en vez de la de bloques usados
-T Imprimir el tipo de sistema de archivos correspondiente
La orden du permite obtener informacin sobre el espacio de disco ocupado por archivos o
(recursivamente) por directorios. Su formato es

du [ opci n ] . . . [<nombrearchi vo >. . . ]


Por defecto du proporciona la informacin de tamao en bloques de 512 bytes, y en caso de
no usarse ningn <nombre-archivo>, la informacin proporcionada corresponder al directorio
de trabajo actual. Las opciones ms importantes son
-a En el caso de directorios imprimir el espacio ocupado por cada archivo no slo el total del
directorio
-c Imprimir una lnea de total general
-h Imprimir los tamaos en formato legible por personas
-s Imprimir solamente una lnea de total para cada argumento
5.3.2. Determinacin del tiempo consumido por una orden (time)
La orden time permite ejecutar una orden del shell y enviar a la salida de error estndar
informacin sobre el tiempo total consumido as como el tiempo de CPU consumido. Su formato
es

ti me [ opci ones ] <comando> [<argumento >. . . ]


Para ms informacin vase la pgina de manual de time.
48 5.3. Miscelnea
5.3.3. Determinacin de la memoria disponible (free)
La orden free permite obtener informacin sobre la cantidad de memoria fsica y de swap
libre y ocupada. Su formato es

f r e e [ opci ones ]
Para ms informacin vase la pgina de manual de free.
5.3.4. Determinacin de la actividad de los usuarios (w)
La orden w permite obtener informacin sobre qu usuarios estn conectados al sistema y
lo que estn haciendo. Su formato es

w [ opci ones ] [<usuari o >]


Para ms informacin vase la pgina de manual de w.
Captulo 6
Control de procesos en UNIX
UNIX es un sistema operativo multiprogramado, lo que signica que el sistema controla
simultneamente la ejecucin de varios procesos.
As pues, el usuario necesita soporte para poder determinar el estado y el modo de trabajo
de los procesos que tenga en curso.
6.1. Informacin sobre procesos (ps)
La orden ps sirve para que el usuario pueda obtener informacin sobre el estado de los
procesos que estn en un momento dado bajo control del sistema operativo. Su formato es

ps [ opci ones ]
Por defecto, ps selecciona todos los procesos que tienen el mismo usuario efectivo que el
usuario en curso y estn asociados al mismo terminal. La informacin proporcionada es el
identicador del proceso, el terminal asociado, el tiempo de CPU consumido y el nombre del
ejecutable. Las opciones ms importantes son
-a Seleccionar todos los procesos salvo los lderes de sesin y los no asociados con un terminal
-e Seleccionar todos los procesos. Se puede escribir -A con el mismo efecto
-f Imprimir informacin detallada sobre los procesos que interesen
-l Imprimir la informacin en formato largo
6.2. Control de trabajos (jobs, fg, bg, kill)
Las rdenes de control de trabajos del shell son habitualmente comandos internos, que per-
miten controlar los trabajos que estn activos en una determinada sesin: terminar determinado
49
50 6.2. Control de trabajos (jobs, fg, bg, kill)
trabajo (matarlo), suspenderlo (pararlo), reanudar un trabajo suspendido o cambiar su modo
de ejecucin.
En UNIX existen dos modos de ejecucin para cualquier proceso: el modo de ejecucin en
primer plano (foreground) y el modo de ejecucin en segundo plano (background).
En cada momento slo puede haber un proceso en primer plano, y ste proceso es el que
utiliza el teclado del terminal.
La forma de obtener informacin sobre los procesos dependientes del shell con indicacin del
nmero de trabajo, el estado en que se encuentra (ejecutando en segundo plano o suspendido)
y el nombre del ejecutable, es utilizar el comando jobs. Su formato es

j obs
Para suspender el proceso en primer plano y pasarlo al segundo plano se utiliza la combina-
cin de teclas <Ctrl>-Z. El proceso que queda en primer plano es el shell.
Un trabajo suspendido puede reanudarse de dos maneras.
Si un trabajo suspendido desea reanudarse de modo que siga ejecutndose en segundo plano
el comando a usar es bg. Su formato es

bg %<numt r abaj o>


donde <num-trabajo> es el nmero de trabajo proporcionado por jobs.
Si un trabajo suspendido desea reanudarse de modo que siga ejecutndose en primer plano
el comando a usar es fg. Su formato es

f g %<numt r abaj o>


donde <num-trabajo> es el nmero de trabajo proporcionado por jobs.
Si se ejecuta fg sobre un trabajo que est ejecutndose en segundo plano, simplemente pasar
a ejecutarse en primer plano.
Si lo que se desea es eliminar un trabajo que est ejecutndose en primer plano se debe usar
la combinacin de teclas <Ctrl>-C.
Si se desea eliminar un trabajo que est ejecutndose en segundo plano, la orden a usar es
kill. Su formato es

k i l l %<numt r abaj o>


donde <num-trabajo> es el nmero de trabajo proporcionado por jobs.
Si se desea suspender un trabajo que est ejecutndose en segundo plano, debe primero
pasarse a primer plano mediante fg y despus suspenderlo usando <Ctrl>-Z.
6.3. Otras operaciones con procesos 51
6.3. Otras operaciones con procesos
6.3.1. Espera durante un tiempo determinado (sleep)
El comando sleep permite esperar una determinada cantidad de tiempo (por defecto medida
en segundos). Su formato es

s l e e p <tiempo>[<s uf i j o >]
donde <tiempo> indica la cantidad de tiempo que se desea esperar. <sujo> permite cambiar
las unidades de <tiempo>. Se puede usar el sujo m para indicar minutos, el sujo h para
indicar horas y el sujo d para indicar das.
6.3.2. No eliminar un proceso al cerrar la sesin (nohup)
La orden nohup permite que la orden del shell que le siga inmediatamente sea ejecutada
de modo que no se elimine el proceso correspondiente aunque se cierre la sesin del shell. Su
formato es

nohup <comando> [<arg >] . . .


donde <comando> [<arg>]... es la orden que debe continuar ejecutndose incluso aunque se
cierre la sesin actual.
Si no se usa la orden nohup, cualquier orden del shell que no haya terminado su ejecucin
cuando se cierra la sesin, ser abortada antes de cerrar la sesin efectivamente.
6.3.3. Envo de seales a un proceso (kill)
Es frecuente que se necesite enviar una noticacin a un proceso acerca de algn acon-
tecimiento que interesa que conozca. El mecanismo que usa UNIX para hacer ese trabajo se
denomina envo de seales.
Para enviar una seal a un proceso se utiliza la orden kill. Esta orden no debe confundirse
con el comando interno del shell del mismo nombre (ver seccin 6.2). Su formato bsico es

k i l l s <seal > <pid >. . .


donde <seal> es el nmero o el nombre de la seal que queremos enviar y <pid> el identicador
del proceso destinatario tal como se obtiene mediante la orden ps (ver seccin 6.1).
El siguiente formato de la orden kill
52 6.3. Otras operaciones con procesos

k i l l l [<seal >]
imprime por defecto una lista con los nombres de las seales disponibles en el sistema (no todos
los sistemas UNIX usan las mismas) y sus respectivos nmeros de seal. Si se indica un nombre
de seal, esta forma proporcionar el nmero correspondiente y viceversa.
Parte II
Uso del compilador C de GNU
53
Captulo 7
Introduccin
El desarrollo prctico de la actividad de programacin con un lenguaje compilado como C,
cuando la formacin previa de programacin se ha desarrollado utilizando un lenguaje inter-
pretado como Java, Python, etc., presenta al alumno un problema aadido al del dominio del
correspondiente lenguaje. En la nueva situacin se necesita manejar una herramienta de desarro-
llo que permita controlar las distintas fases que nos conducen a obtener un programa ejecutable
a partir de los archivos correspondientes escritos en lenguaje fuente.
El proyecto GNU de software libre dispone de un gestor de compilacin para los lenguajes
C y C++, denominado gcc, que puede ocuparse de las diferentes fases del proceso de creacin
de un ejecutable (preproceso, compilacin, ensamblaje, enlace).
En lo que sigue, como es habitual, nos referiremos a gcc como el compilador C de GNU,
aunque la herramienta no realiza slo la tarea de compilacin estrictamente considerada.
7.1. Obtencin de un ejecutable a partir de los archivos
fuente
La obtencin de un ejecutable a partir de archivos fuente conlleva la realizacin de varias
fases en secuencia
1. Preproceso
2. Compilacin
3. Ensamblaje
4. Enlace
La herramienta gcc permite desarrollar esas tareas desde cualquier fase y detenerlas en el
punto que nos interese.
Por defecto, gcc supone que los archivos fuente tienen nombre que utilizan una extensin
c o bien una extensin h. stos ltimos son denominados archivos de cabecera, por lo cual
usaremos la denominacin de archivos fuente slo para los primeros.
55
56 7.1. Obtencin de un ejecutable a partir de los archivos fuente
Figura 7.1: Operacin de preproceso
7.1.1. Preproceso
En esta fase, se realizan sobre cada archivo fuente determinadas operaciones de inclusin de
texto procedente de distintos archivos de cabecera, sustitucin y desarrollo de macros y seleccin
condicional de texto de programa para ser compilado posteriormente.
A partir de un archivo fuente, se obtiene as un archivo preprocesado (unidad de compilacin)
que, ms tarde, ser procesado por el compilador (ver g. 7.1).
7.1.2. Compilacin
Durante esta fase, los compiladores puros producen cdigo objeto para la plataforma hard-
ware sobre la que trabajan, adecuado a la arquitectura de sta y al sistema operativo que ms
tarde tendr que dar soporte a la ejecucin de la aplicacin.
No obstante, la herramienta gcc es una herramienta multiplataforma, y hace ese trabajo
en dos partes. En la fase de compilacin, gcc produce cdigo ensamblador para la plataforma
deseada y ms tarde, el cdigo objeto se obtiene mediante el ensamblaje correspondiente.
En la g. 7.2 se representa la operacin de gcc en la fase de compilacin.
7.1. Obtencin de un ejecutable a partir de los archivos fuente 57
Figura 7.2: Operacin de compilacin
Figura 7.3: Operacin de ensamblaje
7.1.3. Ensamblaje
La herramienta gcc produce un mdulo objeto a partir de cada mdulo ensamblador obtenido
en la fase de compilacin (ver g. 7.3).
7.1.4. Enlace
La fase de enlace realiza la tarea de reunir los distintos mdulos objeto obtenidos de las fases
anteriores y los que se deban extraer de las bibliotecas disponibles en un programa ejecutable
(ver g. 7.4).
Despus de que se han desarrollado estas fases hasta el nal, se dispone de un archivo que
puede ser ejecutado sin la presencia de los archivos fuente, sino solamente con el soporte del
sistema operativo (supuesto que no se usan bibliotecas de enlace dinmico). En otras palabras,
los archivos fuente no son ya necesarios para ejecutar el programa.
No obstante, mientras una aplicacin se encuentra en fase de desarrollo, la correccin de los
errores de programacin que causan mal funcionamiento del ejecutable, requiere generalmente
el uso de una nueva herramienta, denominada depurador, que necesita habitualmente referirse al
cdigo fuente para permitir al programador una traza de la operacin del programa en ejecucin.
As pues, el cdigo fuente deja de ser necesario slo cuando la aplicacin se encuentra en fase
de explotacin.
58 7.1. Obtencin de un ejecutable a partir de los archivos fuente
Figura 7.4: Operacin de enlace
Captulo 8
El compilador C de GNU
8.1. Uso de gcc mediante el shell UNIX
La herramienta gcc puede ejecutarse desde el shell UNIX para realizar todas o algunas de
las fases de creacin de un ejecutable a partir de los archivos fuente que han sido descritas en el
captulo 7.
La orden del shell para desarrollar este trabajo, en una forma simplicada, tiene el formato
siguiente
_
`

gcc [c|S|E] [W <warn>] [std= <standard >] [g | ggdb ]


[ [ I <di r >] . . . ] [ [ L <di r >] . . . ] [o <o ut f i l e >] <i n f i l e > . . .
[l <l i br ar y > . . . ]
El formato anterior slo contiene las opciones ms comunes. Para una informacin comple-
ta sobre las opciones disponibles debe consultarse la pgina de manual de gcc, as como la
informacin que sobre gcc puede obtenerse usando la herramienta info. En todo caso, debe
recordarse que, en general, las opciones no deben agruparse, ya que hay algunas que son de
varios caracteres, y gcc puede interpretar de modo distinto las opciones escritas separadamente
de las agrupadas.
En condiciones normales, gcc pasa de unas fases a otras creando archivos temporales inter-
medios que son eliminados al terminar la operacin completa, pero hay opciones que permiten
que la comunicacin entre las fases consecutivas se realice por medio de tuberas. Para ms
informacin consltese la pgina de manual de gcc.
Las tareas que gcc debe realizar dependen de los archivos que recibe como entrada (denotados
en el formato de la orden como <infile> ...). gcc reconoce los distintos tipos de archivo por
la extensin utilizada en sus nombres. Las alternativas principales son las siguientes
.c Esta extensin se usa para los archivos fuente en lenguaje C
.h Esta extensin se usa para los archivos de cabecera
59
60 8.2. Opciones de uso frecuente
.i Esta extensin se usa para los archivos fuente que no necesitan ser preprocesados
.s Esta extensin se usa para los archivos en ensamblador
.o Esta extensin se usa para los archivos objeto producidos por el ensamblador
Comentaremos ahora el uso de las opciones ms frecuentes.
8.2. Opciones de uso frecuente
8.2.1. Opciones globales (-c, -S, -E, -o <outle>)
La opcin -c se usa para indicar que la tarea de gcc debe detenerse despus de realizada la
operacin de ensamblaje, es decir cuando se hayan producido los archivos objeto correspondien-
tes, supuesto que no haya habido errores.
La opcin -S se usa para indicar que la tarea de gcc debe detenerse despus de realiza-
da la operacin de compilacin, es decir cuando se hayan producido los archivos ensamblador
correspondientes, supuesto que no haya habido errores.
La opcin -E se usa para indicar que la tarea de gcc debe detenerse despus de realizada
la operacin de preproceso, es decir cuando se hayan producido los archivos preprocesados
correspondientes, supuesto que no haya habido errores.
Si no se usa ninguna de las opciones anteriores, se intentar construir un ejecutable a partir
de los archivos de entrada.
La opcin -o, seguida de un nombre de archivo, especica el nombre que se desea para el
archivo de salida. Esto se aplica independientemente de la clase de salida producida, tanto si
es un archivo ejecutable como si es un archivo objeto, un archivo ensamblador o un archivo
preprocesado.
Si se especica la opcin -o cuando hay varios archivos de entrada o cuando se est constru-
yendo un ejecutable, todos los archivos de entrada sern procesados de una vez (en particular
se compilarn todos los archivos fuente) y se generar un nico archivo objeto o un ejecutable.
Si no se especica la opcin -o, y se est construyendo un ejecutable, el nombre de ste ser
a.out. Para los dems archivos de salida, a partir de una entrada source.<x> con una extensin
.<x>, se producir un archivo de salida con nombre source y extensin .o para los archivos
objeto y .s para los archivos ensamblador. Los archivos preprocesados se enviarn a la salida
estndar.
8.2.2. Opciones que controlan los mensajes de aviso (-W <warn>)
La opcin -W permite controlar qu clases de mensajes de aviso (warning) se quieren recibir
durante la operacin de gcc.
Para nuestro uso la nica opcin que utilizaremos ser de la forma -Wall, lo que permitir
que gcc nos proporcione todos los avisos de cualquier clase que se produzcan durante la operacin
de gcc. Para ms informacin consltese la pgina de manual de gcc.
8.2. Opciones de uso frecuente 61
8.2.3. Opciones que controlan el estndar utilizado
(-std = <standard>)
gcc permite utilizar varios dialectos del lenguaje C. La opcin -std permite especicar el
tipo de dialecto usado. Si <standard> se escribe como c89 se usar el estndar iso9899:1990.
Esa ser la nica especicacin que nosotros usaremos. Dicha especicacin admite una forma
simplicada: -ansi. Para ms informacin sobre otros estndares consltese la pgina de manual
de gcc.
8.2.4. Opciones que controlan la incorporacin de cdigo para depu-
racin (-g, -ggdb)
Para incorporar a un ejecutable el cdigo que permite luego utilizar un depurador para
investigar su posible mal funcionamiento, puede usarse la opcin -g si se va a usar un depurador
genrico. La opcin -ggdb permite incorporar cdigo de depuracin especcamente asociado
al depurador GNU, denominado gdb. Nosotros, para el trabajo habitual siempre incluiremos
una de estas opciones, con objeto de que luego, nuestros ejecutables se puedan siempre depurar.
Para ms informacin consltese la pgina de manual de gcc.
8.2.5. Opciones que describen los directorios de residencia de las ca-
beceras (-I<dir>)
gcc usa una cadena de directorios, que depende de la conguracin de la herramienta, para
buscar los archivos de cabecera necesitados en las operaciones de preproceso. En particular,
las cabeceras de la biblioteca estndar se encuentran en directorios incluidos en esta cadena de
directorios, y para ellas no es necesario usar la opcin -I. Si se usa la opcin -I seguida de un
nombre de directorio, se aade ese directorio en cabeza de la lista de bsqueda. Si el directorio
ya gura en la lista de bsqueda, la opcin se ignora.
Por lo tanto, cuando nosotros queremos manejar alguna cabecera no estndar (por ejemplo
nuestra) en nuestro cdigo fuente, con la directiva #include <cabecera.h> o bien #include
cabecera.h, necesitamos generalmente usar la opcin -I para indicar el directorio en que
deben buscarse esas cabeceras.
8.2.6. Opciones que describen los directorios de residencia de las bi-
bliotecas (-L<dir>)
gcc usa una cadena de directorios, que depende de la conguracin de la herramienta, para
buscar las bibliotecas necesitadas en la operacin de enlace. Si se usa la opcin -L seguida de
un nombre de directorio, se aade ese directorio a la lista de bsqueda.
As pues, el esquema de bsqueda de las bibliotecas necesarias en la fase de enlace sigue una
pauta anloga a la de las cabeceras en la fase de preproceso
62 8.2. Opciones de uso frecuente
8.2.7. Opciones que describen las bibliotecas que deben usarse en el
proceso de enlace (-l<library>)
Cuando al intentar construir un ejecutable (durante el proceso de enlace) gcc encuentra que
ciertas funciones utilizadas no se encuentran denidas en los archivos objeto que participan en
la operacin, busca por defecto esas funciones en la biblioteca estndar. Si las encuentra, las
extrae de la biblioteca y continua el proceso de enlace. En otro caso la herramienta informa del
error correspondiente y el ejecutable no llega a ser generado.
Si las funciones que necesitamos no pertenecen a la biblioteca estndar, o incluso, en la con-
guracin ms corriente, son funciones matemticas de la biblioteca estndar, debemos indicar
a gcc en qu biblioteca debe buscar. La opcin -l, seguida de un nombre de biblioteca permite
pasar a gcc esa informacin. Para indicar a gcc en qu directorio buscar la biblioteca vase la
seccin 8.2.6.
La biblioteca matemtica estndar para gcc se denomina libm.a (para la versin de enlace
esttico) o bien libm.so (para la versin de enlace dinmico, que es la utilizada normalmente),
por lo cual, cuando se necesita utilizar alguna funcin de clculo matemtico de la biblioteca
estndar, nuestro cdigo debe enlazarse con los mdulos de esta biblioteca usando la opcin -lm
(se usa el nombre de la biblioteca sin el prejo lib y sin la extensin).
Parte III
El depurador gdb de GNU
63
Captulo 9
Introduccin
Durante el desarrollo de cualquier aplicacin, con independencia del lenguaje que se use para
ello, se producen errores de programacin que pueden ser detectados en diferentes fases del ciclo
de trabajo.
Cuando, como es nuestro caso, estamos interesados en el ciclo de desarrollo utilizado con
un lenguaje compilado como C, esos errores pueden producirse en cualquier fase del proceso de
generacin del ejecutable (errores en tiempo de compilacin o enlace) o bien se producen cuando
se ejecuta la aplicacin (errores en tiempo de ejecucin).
9.1. Un programa ejemplo
Para distinguir cmo se presentan y en qu momento se detectan los diferentes tipos de
errores utilizaremos un programa ejemplo.
Su especicacin ser la siguiente: El programa debe obtener de la lnea de rdenes una serie
de opciones seguida de una serie de argumentos suplementarios. Las opciones son cadenas de
caracteres que comienzan por el carcter -. Los argumentos suplementarios son cadenas de
caracteres cualesquiera, de las cuales la primera no puede comenzar por el carcter -.
El programa debe enviar a la salida estndar una lnea con las opciones que haya en la
lnea de rdenes separadas por espacios en blanco. Despus debe producir una lnea para cada
argumento suplementario donde guren ese argumento y la correspondiente longitud de la cadena
de caracteres.
Supongamos que nuestra solucin inicial para el programa ejemplo sea la descrita en el listado
9.1
El compilador detecta los errores sintcticos de nuestro programa en tiempo de compilacin.
Cuando intentamos generar el correspondiente ejecutable obtenemos el resultado que puede
verse en la gura 9.1.
Como puede observarse se obtiene un informe de errores que esencialmente nos indica que se
ha alcanzado el nal de la funcin main sin haber devuelto el valor entero que indica su cabecera,
y despus hay ms texto que causa otros errores.
65
66 9.1. Un programa ejemplo
1
#include <s t di o . h>
3 #include <s t r i ng . h>
5 void Pri nt I nf orme ( const char cadena ) ;
7 i nt main( i nt argc , char argv [ ] )
{
9
pr i nt f ( "Las opciones son: " ) ;
11 while(argc > 0 && ++argv [ 0 ] == -)
pr i nt f ( " %s " , ++argv ) ;
13 }
15 pr i nt f ( "\n" ) ;
17 pr i nt f ( "Otros argumentos de la linea de ordenes\n" ) ;
while ( argv++){
19 Pri nt I nf orme ( argv ) ;
argv++;
21 }
23 return 0;
}
Listado 9.1: Programa ejemplo. Versin 0a
Figura 9.1: Listado de errores de compilacin
9.1. Un programa ejemplo 67
1
#include <s t di o . h>
3 #include <s t r i ng . h>
5 void Pr i nt I nf orme ( const char cadena ) ;
7 i nt main( i nt argc , char argv [ ] )
{
9
pr i nt f ( "Las opciones son: " ) ;
11 while(argc > 0 && ++argv [ 0 ] == -)
pr i nt f ( " %s " , ++argv ) ;
13
15 pr i nt f ( "\n" ) ;
17 pr i nt f ( "Otros argumentos de la linea de ordenes\n" ) ;
while ( argv++){
19 Pri nt I nf orme ( argv ) ;
argv++;
21 }
23 return 0;
}
Listado 9.2: Programa ejemplo. Versin 0b
El error bsico consiste en que en el primer bucle while el cuerpo est delimitado por una
llave de n de bloque (carcter } en la lnea 13 del listado 9.1) pero no la correspondiente de
comienzo. En realidad la llave de n de bloque es innecesaria, puesto que el cuerpo del bucle
slo consiste en una sentencia.
Si corregimos el error eliminando ese delimitador, tendramos nuestro programa en la forma
descrita en el listado 9.2
Cuando intentamos generar el correspondiente ejecutable obtenemos el resultado que puede
verse en la gura 9.2.
El informe ahora contiene errores que no son de sintaxis. Es el enlazador el que nos informa
de que no es capaz de encontrar la funcin PrintInforme. Efectivamente, nuestro programa no
incorpora una denicin de la funcin citada, sino slo la declaracin de su prototipo.
Si incorporamos la denicin de la funcin PrintInforme, nuestro programa podra quedar
en la forma descrita en el listado 9.3
Ahora, nuestro intento de generar el ejecutable tiene xito sin que se produzca ningn error
en las fases de compilacin y enlace.
No obstante, si intentamos ejecutar el programa producido con la orden
68 9.1. Un programa ejemplo
1
#include <s t di o . h>
3 #include <s t r i ng . h>
5 void Pri nt I nf orme ( const char cadena ) ;
7 i nt main( i nt argc , char argv [ ] )
{
9
pr i nt f ( "Las opciones son: " ) ;
11 while(argc > 0 && ++argv [ 0 ] == -)
pr i nt f ( " %s " , ++argv ) ;
13
pr i nt f ( "\n" ) ;
15
pr i nt f ( "Otros argumentos de la linea de ordenes\n" ) ;
17 while ( argv++){
Pri nt I nf orme ( argv ) ;
19 argv++;
}
21
return 0;
23 }
25 void Pri nt I nf orme ( const char cadena )
{
27 i nt l ongi t ud ;
29 l ongi t ud = s t r l e n ( cadena ) ;
pr i nt f ( " %s\tlongitud= %d\n" , cadena , l ongi t ud ) ;
31
return ;
33 }
Listado 9.3: Programa ejemplo. Versin 1
9.2. Depuracin de un ejecutable 69
Figura 9.2: Listado de errores de enlace

. / ej empl ogdb1 al c menos una t r e s "dos y cuat r o "


obtenemos la salida que se puede observar en la gura 9.3.
Como puede observarse, nuestro programa no produce la salida esperada, pero ahora, para
encontrar los errores que pueda haber (errores en tiempo de ejecucin), no disponemos de un
informe de errores como en los casos anteriores, sino que sabemos que nuestro programa es
incorrecto porque la salida que produce no es la esperada.
9.2. Depuracin de un ejecutable
Podemos intentar localizar los errores de nuestro programa que hacen que no produzca la
salida esperada inspeccionando el cdigo fuente, pero en un programa medianamente complejo
eso resulta inviable.
Una prctica frecuente consiste en insertar sentencias de escritura que permitan seguir la
traza de ejecucin del programa, con objeto de determinar dnde es incorrecta su lgica. Esa
solucin es inadecuada, al menos porque eso introduce sentencias innecesarias para la lgica
del programa, que ms tarde habr que eliminar, o al menos, evitar que se ejecuten cuando el
programa se ponga en produccin. Ello tiene el riesgo de que nuestro programa deje de funcionar
como lo haca con las sentencias auxiliares que nos hayan permitido corregirlo.
Un depurador simblico (abreviadamente un depurador) es una herramienta de desarrollo
que permite observar, paso a paso si es necesario, la ejecucin de un programa, para que el
programador pueda determinar dnde se encuentran los fallos del programa que hacen que se
70 9.2. Depuracin de un ejecutable
Figura 9.3: Salida de la versin 1
comporte en tiempo de ejecucin de una manera no acorde con su especicacin. Para realizar
esa tarea, el depurador no necesita que se modique el cdigo fuente del programa, lo cual
permite que, despus de corregidos los errores, nuestro programa pueda ponerse en produccin
sin otros cambios.
En las siguientes pginas se describir el uso elemental del depurador gdb de GNU para
resolver el problema de comprobar la lgica de un programa, utilizando para ello el mismo
ejemplo que hemos usado hasta aqu.
Captulo 10
El depurador gdb de GNU
El funcionamiento de un depurador simblico se basa en incorporar al ejecutable referencias
a las sentencias del cdigo fuente durante las fases de compilacin y enlace. Para ello es impres-
cindible que el compilador y el enlazador hagan ese trabajo, lo cual, en el caso del sistema de
desarrollo GNU se realiza utilizando la opcin -g en la lnea de rdenes del gestor de compilacin
y enlace gcc (vase la seccin 8.2.4). En nuestro caso, y dado que utilizaremos el depurador gdb
de GNU, podemos utilizar la opcin -ggdb para poder usar las caractersticas particulares de
dicho depurador.
Por tanto, como regla general, durante el desarrollo de cualquier aplicacin, deber utilizarse
sistemticamente la opcin -ggdb (o bien -g) en las compilaciones de los archivos fuente y en
los procesos de enlace que conducen a la generacin de nuestros ejecutables, con objeto de
poder utilizar el depurador para inspeccionar la ejecucin de nuestros programas si ello resulta
necesario.
Por otra parte, debe sealarse que, para que el depurador pueda realizar su trabajo, es
necesario que aquel pueda acceder a los archivos fuente, donde reside el cdigo que ha sido
compilado y luego enlazado para formar el ejecutable, porque, como ya se ha dicho, el ejecutable,
cuando se ha construido utilizando la opcin de depuracin, slo contiene referencias a las
sentencias fuente, y no las sentencias mismas. Por tanto, no ser posible inspeccionar la traza
de ejecucin de las funciones de nuestro programa de las que no dispongamos del cdigo fuente.
No obstante, ello no debe causar problemas especiales, puesto que el cdigo que supuestamente
debemos someter a depuracin es el producido por nosotros, del cual, naturalmente, s tendremos
el cdigo fuente.
Para los ejemplos que utilizaremos en el presente captulo supondremos que nuestro directorio
de trabajo actual es el que contiene nuestro ejecutable ejemplo y que los archivos fuente corres-
pondientes se encuentran situados en el directorio en el que se encontraban cuando se gener
aquel. En particular supondremos que nuestro archivo fuente de partida ser ejemplo-gdb1.c
correspondiente al listado 9.3, que estar situado en el directorio <HOME>/gdb-ejemplo, el cual
ser nuestro directorio de trabajo.
Nuestro ejecutable se obtendr mediante la orden

gcc Wall ans i ggdb o ej empl ogdb1 ej empl ogdb1 . c


71
72 10.1. Una sesin de depuracin con gdb
Figura 10.1: Pantalla de presentacin del depurador gdb
lo cual dar lugar a que dicho ejecutable (denominado ejemplo-gdb1), que como ya se vio en
la seccin 9.1 se genera sin errores de compilacin ni enlace, contenga el cdigo de depuracin
correspondiente.
Como tambin se vio en la gura 9.3, la salida del programa no es la esperada, por lo cual,
se proceder ahora a usar el depurador gdb para seguir la traza de ejecucin con esos mismos
datos en la lnea de rdenes, con objeto de determinar en qu consisten los posibles errores.
10.1. Una sesin de depuracin con gdb
La forma ms habitual de comenzar una sesin de depuracin es invocar el depurador en
la lnea de rdenes con un argumento, que es el nombre del ejecutable que debe depurarse. En
nuestro caso sera

gdb ej empl ogdb1


lo cual producir una pantalla de presentacin del depurador tal como se observa en la gura
10.1, en la que se puede observar que el prompt ahora ha cambiado de forma (es (gdb)) para
indicarnos que quien nos atiende ahora es el depurador y no el shell como antes.
Las rdenes que se den a partir de ahora se envan al depurador, y cuando hayamos terminado
la sesin de depuracin deberemos cerrarla (con la orden q) para volver al shell normal.
10.1. Una sesin de depuracin con gdb 73
Figura 10.2: Paso de los argumentos de la lnea de rdenes
10.1.1. Argumentos de la lnea de rdenes
Nuestro ejecutable reciba argumentos a travs de la lnea de rdenes. Antes de intentar
ejecutarlo con el depurador debemos informar a ste de cules son los argumentos que debe
pasar a nuestro ejecutable. La orden correspondiente es set args. Su formato es

s e t ar gs [<argumento> . . . ]
donde la lista de argumentos es la que deseemos pasar luego al programa en depuracin (excluido
el nombre del programa).
En nuestro caso utilizaremos los mismos que causaban los errores observados en la gura
9.3.

s e t ar gs al c menos una t r e s "dos y cuat r o "


con lo cual tendremos en el terminal la salida indicada en la gura 10.2.
10.1.2. Puntos de ruptura (breakpoints)
La siguiente tarea es decirle al depurador en qu lugar del programa queremos que detenga la
ejecucin normal para que nosotros podamos inspeccionar lo que sucede a partir de ese punto.
La orden correspondiente es br y va seguida o bien de un nombre de funcin, o bien de un
74 10.1. Una sesin de depuracin con gdb
Figura 10.3: Punto de ruptura
nombre de archivo fuente seguido del carcter : y de un nmero de lnea. En el primer caso
el depurador detendr el ujo de ejecucin del programa en cuanto se realice una llamada a la
funcin antes de ejecutar su primera sentencia. En el segundo caso el depurador detendr el ujo
de ejecucin en cuanto corresponda ejecutar la lnea del archivo citado o la primera ejecutable
que haya despus de ella. En ambos casos la ejecucin se detiene sin haber ejecutado la sentencia
correspondiente.
En nuestro caso, queremos trazar la ejecucin desde el principio, as que lo ms cmodo es
usar la primera forma,

br main
con lo que obtendremos en el terminal el resultado indicado en la gura 10.3.
En ella podemos observar que nuestro punto de ruptura se encuentra situado en la lnea 10
del archivo ejemplo-gdb1.c.
10.1.3. Ejecucin del programa
Ahora debemos ordenar al depurador que ejecute el programa con las condiciones anterior-
mente establecidas. Para ello se utiliza la orden run. Su formato es el siguiente

run [<argumento> . . . ]
10.1. Una sesin de depuracin con gdb 75
Figura 10.4: Ejecucin hasta el punto de ruptura
En la lista de argumentos se pueden pasar los argumentos de la lnea de rdenes con los
que se desee ejecutar el programa si no se han especicado antes mediante set args (vase
la seccin 10.1.1). Al igual que con set args, en esos argumentos no se especica de nuevo el
nombre del ejecutable.
En nuestro caso ejecutaremos

run
La respuesta del depurador es la que se observa en la gura 10.4. Como puede verse, la
ejecucin se ha detenido antes de ejecutar la primera sentencia de la funcin main, que se
encuentra en la lnea 10 del archivo fuente. En adelante nos referiremos a las sentencias por su
nmero de lnea.
Desde ahora, las rdenes al depurador controlarn la ejecucin del programa. Tpicamente
necesitaramos ahora ejecutar la sentencia nmero 10. La ejecucin de la sentencia inmediata
cuando el programa est detenido se logra mediante la orden n

n
lo cual, en nuestro caso produce el resultado que se observa en la gura 10.5, donde podemos ver
que se ha enviado la cadena de caracteres Las opciones son: al stream de salida estndar
(no se ha escrito en una lnea del terminal porque, en el actual modo de trabajo de ste, no se
escribir nada en l mientras no se complete la lnea, es decir, mientras no se escriba un carcter
de nueva lnea).
76 10.1. Una sesin de depuracin con gdb
Figura 10.5: Ejecucin de la sentencia 10
Adems observamos que la sentencia inmediata que ser ejecutada (la nmero 11) es la
cabecera del bucle while que tiene por objeto obtener de la lnea de rdenes todas los argumentos
que sean opciones (todos los que comienzan por el carcter - hasta el primero que no comience
por dicho carcter exclusive).
Para ejecutar la sentencia 11 podemos usar de nuevo la orden n como antes o bien pulsar
<RET>, lo cual podr ser utilizado en cualquier momento para repetir la ltima orden emitida.
Nuestro resultado puede verse en la gura 10.6.
Lo que observamos es que la siguiente sentencia a ejecutar (la 14) est ya fuera del bucle
de obtencin de las opciones. Cuando la ejecutemos se escribir la lnea correspondiente en el
terminal, con el rtulo de la sentencia 10 seguido del carcter de nueva lnea, puesto que no
se ha encontrado ninguna opcin. Por otra parte, la siguiente sentencia a ejecutar ser la 16.
Efectivamente, eso es lo que observamos en la gura 10.7.
Es evidente el mal comportamiento del programa. Con nuestros argumentos en la lnea de
rdenes hay varias opciones que no han sido localizadas por el bucle while de la lnea 11, que,
en consecuencia, est programado incorrectamente. No se ha ejecutado el cuerpo del bucle ni
una sola vez, as que el problema est en la expresin de control del bucle. En ella se usa un
operador and lgico, en el que el primer operando lleva la cuenta de argumentos procesados en
la lnea de rdenes, en la que se empieza descontando el primero para no tener en cuenta el
nombre del programa y resultar falsa cuando se acaben los argumentos de la lnea de rdenes.
Esa condicin parcial es correcta.
El otro operando intenta determinar si el primer carcter del argumento correspondiente de
la lnea de rdenes es un signo -. Si es as, se trata de una opcin, que se enviar a la salida
estndar y se iterar de nuevo mientras en los nuevos argumentos el primer carcter siga siendo
un signo -.
10.1. Una sesin de depuracin con gdb 77
Figura 10.6: Ejecucin de la sentencia 11
Figura 10.7: Ejecucin de la sentencia 14
78 10.1. Una sesin de depuracin con gdb
Figura 10.8: Orden de salida del depurador
Sin embargo la expresin *++argv[0] no tiene el valor del primer carcter del argumento
de la lnea de rdenes en cada caso. En efecto: inicialmente argv[0] es un puntero al primer
carcter del primer argumento de la lnea de rdenes (el nombre del programa). ++argv[0]
es un puntero al segundo carcter de ese argumento, no al primer carcter del segundo
argumento, que es lo que necesitamos, as que *++argv[0] es el segundo carcter del nom-
bre del programa, que en nuestro caso es un carcter h (el nombre de nuestro programa es
/home/alumno/gdb-ejemplo/ejemplo-gdb1).
Ahora debemos corregir ese error. La expresin correcta es (*++argv)[0], la cual incrementa
argv para apuntar al siguiente argumento de la lnea de rdenes (inicialmente el segundo) y toma
el valor del primer carcter. Para ello debemos salir del depurador mediante la orden q.

q
La salida es la observada en la gura 10.8, en la que el depurador pide conrmacin, puesto
que el programa sigue en ejecucin y posteriormente, termina y el shell normal vuelve a tomar
el control.
Ahora debemos modicar el cdigo fuente en la lnea 11, volver a generar el ejecutable y
ejecutar de nuevo para ver si nuestro problema se ha solucionado. La nueva versin del cdigo
puede verse en el listado 10.1.
El resultado de la generacin del nuevo ejecutable y la ejecucin con nuestros datos puede
verse en la gura 10.9.
Como puede observarse, no hay errores de compilacin ni enlace pero la salida de la versin
2 sigue siendo incorrecta. Las opciones no se capturan bien y al listar el resto de los argumentos
se produce una excepcin de memoria.
10.1. Una sesin de depuracin con gdb 79
1
#include <s t di o . h>
3 #include <s t r i ng . h>
5 void Pr i nt I nf orme ( const char cadena ) ;
7 i nt main( i nt argc , char argv [ ] )
{
9
pr i nt f ( "Las opciones son: " ) ;
11 while(argc > 0 && (++argv ) [ 0 ] == -)
pr i nt f ( " %s " , ++argv ) ;
13
pr i nt f ( "\n" ) ;
15
pr i nt f ( "Otros argumentos de la linea de ordenes\n" ) ;
17 while ( argv++){
Pri nt I nf orme ( argv ) ;
19 argv++;
}
21
return 0;
23 }
25 void Pr i nt I nf orme ( const char cadena )
{
27 i nt l ongi t ud ;
29 l ongi t ud = s t r l e n ( cadena ) ;
pr i nt f ( " %s\tlongitud= %d\n" , cadena , l ongi t ud ) ;
31
return ;
33 }
Listado 10.1: Programa ejemplo. Versin 2
80 10.1. Una sesin de depuracin con gdb
Figura 10.9: Salida de la versin 2
En la gura 10.10 podemos ver la situacin de partida para seguir la traza de ejecucin de
la versin 2 del programa desde la funcin main y con los mismos argumentos que en el caso de
la versin 1.
Si ejecutamos la orden n (dos veces) para ejecutar las sentencias de las lneas 10 y 11,
podemos ver que ahora s ejecutamos el cuerpo del bucle. En la primera iteracin se deber
imprimir la primera opcin. No obstante, lo que realmente se va a imprimir es el valor de la
expresin *++argv. Podemos decirle al depurador que nos informe del valor de la expresin
ejecutando la orden p con un operando que es la expresin a evaluar.

p ++argv
El resultado puede verse en la gura 10.11. Puede observarse que la orden p permite obtener
el valor de una expresin, y en particular, que si esa expresin es un puntero a una cadena de
caracteres, lo que se obtiene es la cadena completa.
Ahora podemos ver por qu la salida de nuestro programa es incorrecta. La primera iteracin
del bucle de captura de las opciones no enva a la salida estndar la primera opcin, sino la
segunda directamente. Ello se debe a que la expresin utilizada para imprimir (*++argv) es
incorrecta. Justo antes de ejecutar la sentencia 12, argv apunta al puntero que a su vez apunta
a la cadena que contiene la opcin, as que la expresin que debera imprimirse mediante printf
es *argv omitiendo el operador ++.
Debemos, por tanto, salir del depurador, corregir el programa fuente, regenerar el ejecutable
y ejecutar de nuevo para ver el comportamiento ahora. El cdigo fuente corregido puede verse
en el listado 10.2.
10.1. Una sesin de depuracin con gdb 81
Figura 10.10: Ejecucin del depurador con la versin 2 del programa
Figura 10.11: Impresin del valor de una expresin
82 10.1. Una sesin de depuracin con gdb
1
#include <s t di o . h>
3 #include <s t r i ng . h>
5 void Pri nt I nf orme ( const char cadena ) ;
7 i nt main( i nt argc , char argv [ ] )
{
9
pr i nt f ( "Las opciones son: " ) ;
11 while(argc > 0 && (++argv ) [ 0 ] == -)
pr i nt f ( " %s " , argv ) ;
13
pr i nt f ( "\n" ) ;
15
pr i nt f ( "Otros argumentos de la linea de ordenes\n" ) ;
17 while ( argv++){
Pri nt I nf orme ( argv ) ;
19 argv++;
}
21
return 0;
23 }
25 void Pri nt I nf orme ( const char cadena )
{
27 i nt l ongi t ud ;
29 l ongi t ud = s t r l e n ( cadena ) ;
pr i nt f ( " %s\tlongitud= %d\n" , cadena , l ongi t ud ) ;
31
return ;
33 }
Listado 10.2: Programa ejemplo. Versin 3
10.1. Una sesin de depuracin con gdb 83
Figura 10.12: Salida de la versin 3
La salida de la nueva versin puede verse en la gura 10.12. Observamos que no hay errores
de compilacin ni enlace y que ahora las opciones se obtienen correctamente, pero al listar
los argumentos suplementarios (los que van a continuacin de las opciones), el programa sigue
fallando. No se listan ms que algunos y al nal se obtiene una excepcin de memoria.
Volveremos por tanto a ejecutar la nueva versin del programa bajo control del depurador
con los mismos datos que en los casos anteriores. Nuestro punto de ruptura lo situaremos ahora
al comienzo del segundo bucle while (lnea 17 del archivo fuente), que es el que debe imprimir
el resto de los argumentos y funciona incorrectamente. Al ejecutar, obtendremos la situacin
mostrada en la gura 10.13.
Podemos observar que se ha producido la impresin correcta de la lnea del informe de salida
que contiene las opciones de la lnea de rdenes y la impresin del rtulo de cabecera del informe
de los otros argumentos. Despus el depurador ha detenido la ejecucin al comienzo del bucle
while que debe imprimir esos argumentos.
Podemos ver cul es el siguiente argumento a procesar imprimiendo el valor de *argv y
despus ejecutar la lnea 17, lo cual nos llevar a detenernos antes de ejecutar la primera iteracin
del bucle. La situacin sera la de la gura 10.14.
Ahora no nos interesa usar la orden n para que el depurador ejecute la sentencia 18. Ello
ejecutara directamente la llamada a la funcin PrintInforme y la ejecucin se detendra antes
de ejecutarse la sentencia 19. Lo que nos interesa es que la ejecucin contine paso a paso dentro
de la funcin PrintInforme. Esto puede conseguirse mediante la orden s.

s
84 10.1. Una sesin de depuracin con gdb
Figura 10.13: Ejecucin del depurador con la versin 3 del programa
Figura 10.14: Primera iteracin del bucle de impresin de argumentos
10.1. Una sesin de depuracin con gdb 85
Figura 10.15: Traza de una funcin mediante la orden s
Si ejecutamos esa orden, el resultado que obtendremos es el mostrado en la gura 10.15.
Podemos observar que el depurador nos informa del valor del argumento que se pasa a la funcin.
En nuestro caso, la cadena --tres. Pero esto no es lo que esperbamos. El argumento que
debera haberse pasado es la cadena una. Ahora est claro por qu obtenemos --tres en
la primera lnea del informe de argumentos en nuestra ejecucin (errnea) del programa (ver
gura 10.12).
Si ahora ejecutamos la orden n, podemos almacenar en longitud la longitud de la cadena,
y luego, mediante la orden p podemos ver el valor de esa longitud. Si ahora ejecutamos n
repetidamente, obtendremos la primera lnea del informe, luego se ejecutar la sentencia de nal
de la funcin PrintInforme y se volver a la funcin main en la lnea 19; despus se vuelve de
nuevo a la cabecera del bucle. Todo ello puede verse en la gura 10.16.
La funcin PrintInforme hace su trabajo correctamente. Como hemos visto, lo que sucede
es que se le pasa un argumento incorrecto. En la cabecera del bucle se comprueba si *argv no
es nulo para ejecutar el cuerpo del bucle, y adems se incrementa argv, con nimo de utilizar
el siguiente argumento de la lnea de rdenes en la iteracin siguiente. Pero esto ltimo es
incorrecto, porque ello afecta a la llamada a PrintInforme. Es necesario modicar la sentencia
17 para no incrementar argv. El cambio de argumento de la lnea de rdenes lo har la sentencia
19.
Por otra parte este error explica la excepcin de memoria que obtenemos al nal. Al incre-
mentar indebidamente argv (de hecho lo incrementamos dos veces una en la lnea 17 y otra en
la 19) nos pasamos del nal de la tabla de punteros sin detectar el puntero nulo que seala su
n.
Como siempre, abortaremos la ejecucin del depurador, corregiremos el error en el programa
fuente, reconstruiremos el ejecutable y realizaremos la ejecucin de prueba. El cdigo corregido
puede verse en el listado 10.3. La salida de ejecucin puede verse en la gura 10.17.
86 10.1. Una sesin de depuracin con gdb
Figura 10.16: Primera ejecucin de la funcin PrintInforme
Figura 10.17: Salida de la versin nal
10.1. Una sesin de depuracin con gdb 87
1
#include <s t di o . h>
3 #include <s t r i ng . h>
5 void Pr i nt I nf orme ( const char cadena ) ;
7 i nt main( i nt argc , char argv [ ] )
{
9
pr i nt f ( "Las opciones son: " ) ;
11 while(argc > 0 && (++argv ) [ 0 ] == -)
pr i nt f ( " %s " , argv ) ;
13
pr i nt f ( "\n" ) ;
15
pr i nt f ( "Otros argumentos de la linea de ordenes\n" ) ;
17 while ( argv ){
Pri nt I nf orme ( argv ) ;
19 argv++;
}
21
return 0;
23 }
25 void Pr i nt I nf orme ( const char cadena )
{
27 i nt l ongi t ud ;
29 l ongi t ud = s t r l e n ( cadena ) ;
pr i nt f ( " %s\tlongitud= %d\n" , cadena , l ongi t ud ) ;
31
return ;
33 }
Listado 10.3: Programa ejemplo. Versin nal
88 10.2. Sugerencias
Ahora la salida obtenida es correcta para los datos utilizados y no se produce la excepcin
de memoria que antes originaba la terminacin anormal de la ejecucin del programa.
10.1.4. Otras rdenes tiles del depurador gdb
Durante la ejecucin de un programa bajo control del depurador gdb pueden utilizarse otras
rdenes que pueden ser de utilidad en otras situaciones. Una de las ms comunes es la orden l.
Su formato es

l [ ][ <numerodel i ne a >]
La orden l cuando se usa sin argumentos opcionales, lista las lneas del archivo fuente en
torno a la sentencia que vaya a ejecutarse (tpicamente cuando se usa por primera vez un
intervalo de 10 lneas en total). Ello sirve para podernos situar en el cdigo fuente y saber qu
sentencias hay antes o despus de la actual. Si se ejecuta l repetidamente se listan las lneas en
torno a la ltima listada la vez anterior.
Si se especica <numero-de-linea> se listan las lneas en torno a la linea indicada, no la
que toca ejecutar. Si se especica el signo - se listan las lneas previas a la actual o a la que
se indique.
Para ms informacin sobre las rdenes del depurador gdb consltese la pgina de informa-
cin sobre el depurador

i nf o gdb
en la lnea de rdenes del shell normal. La pgina de manual normal de gdb contiene un infor-
macin limitada.
10.2. Sugerencias
La solucin discutida en la seccin 10.1.3 para el programa ejemplo en su versin nal daba
una salida correcta para la lnea de rdenes utilizada, pero sigue siendo una solucin incorrecta.
Vase por ejemplo su comportamiento cuando se utiliza una lnea de rdenes vaca.
Se recomienda al lector que utilice el depurador para ver qu es lo que sucede y corrija el
problema como ejercicio para utilizar las tcnicas anteriores.
Parte IV
La utilidad make de GNU
89
Captulo 11
Introduccin
En el mbito del desarrollo y el mantenimiento de software, la realizacin de tareas complejas
basadas en el uso de mltiples recursos que son generados separadamente, es un proceso que,
cuando se realiza manualmente, es tedioso por lo repetitivo y muy propenso a errores.
Tomemos como ejemplo la construccin de uno o varios ejecutables a partir de los archivos
fuente en un ciclo de edicin-compilacin-enlace. Las operaciones de edicin de los archivos
fuente se realizan de modo interactivo y producen los recursos de partida para las otras dos
fases del ciclo de construccin, que, a su vez, se desarrollan en modo batch.
Si la compilacin de los archivos fuente se intenta hacer desde la lnea de rdenes del shell,
obtendremos frecuentemente informes de error correspondientes a los posibles errores sintcticos
que haya en los archivos fuente, lo cual nos llevar a intentar corregirlos y a las correspondientes
recompilaciones. El problema no es grave mientras nuestro proyecto se compone de unos pocos
archivos fuente, pero est clara la dicultad de controlar el proceso manualmente en cuanto la
escala aumenta.
Aparte de ello, debe tenerse en cuenta que, por razones de economa, deberan recompilarse
slo aquellos archivos en los que se hubieran registrado errores, y no los dems, pero lo nico
que es verdaderamente simple es recompilar todo cada vez, lo que, cuando la escala aumenta,
es inaceptable.
El asunto se complica si tenemos en cuenta que los productos de las compilaciones se deben
usar como archivos de entrada para la fase de enlace, en la que tambin pueden producirse
errores, que para ser corregidos pueden necesitar modicar los archivos fuente y por tanto
causar que deba realizarse al menos una recompilacin parcial.
Por ltimo, si nuestros ejecutables no funcionan como se esperaba, habr que modicar los
fuentes, y de nuevo nos encontramos con el mismo problema.
Las consideraciones anteriores slo se han referido al ciclo de construccin bsico, pero debe-
mos tener en cuenta que, durante el desarrollo, se suelen intentar mejoras en las implementacio-
nes, lo que conduce a nuevas versiones de algunos de los archivos fuente, con las consecuencias
correspondientes sobre la generacin de los ejecutables respectivos, proceso en el cual, algunos
fuentes anteriores no necesitan recompilarse pero otros s, etc.
Resulta evidente que las mismas consideraciones pueden hacerse respecto a otras tareas co-
munes en el tratamiento de informacin, como la generacin y mantenimiento de documentacin,
91
92
de donde se deriva el inters que, en el mbito profesional, tiene el uso de herramientas que nos
permitan controlar y automatizar estos procesos.
La utilidad make se usa para resolver esta clase de problemas y las siguientes pginas estn
dedicadas a una breve introduccin al uso elemental de la versin GNU de dicha herramienta
en el desarrollo de aplicaciones en lenguaje C, aunque gran parte de lo que se tratar puede
aplicarse casi sin cambios a la solucin del problema anlogo en otros lenguajes de programacin
o en otros tipos de tareas, as como a otras versiones de la utilidad make presentes en diferentes
sistemas de desarrollo.
Captulo 12
La utilidad make de GNU
Como ya hemos visto en el captulo 11, la utilidad make, en cualquiera de sus versiones,
permite la generacin y el mantenimiento ordenado de los archivos objeto y los ejecutables que
se obtienen a partir de otros archivos fuente, reduciendo las operaciones de compilacin y enlace
al mnimo necesario.
Para realizar su tarea, make utiliza un archivo denominado genricamente makele en el que
el programador especica un conjunto de reglas que make debe aplicar al objeto de conseguir
sus objetivos. La forma de especicar dichas reglas y su contenido son el objeto del presente
captulo.
La utilidad make se ejecuta habitualmente desde la lnea de rdenes del shell y el formato de
la orden es

make [f <makef i l e >] [ opci ones ] . . . [ o bj e t i vo s ] . . .


La opcin ms importante es
-f Seguida de un nombre de archivo hace que ese archivo sea utilizado como makele. Si no
se usa la opcin, se utilizar por defecto un archivo en el directorio actual denominado
makefile o, si ese no existe, uno denominado Makefile
La orden make puede contener como argumentos opcionales varios objetivos de las reglas que
guren en el archivo makele. Si en la orden gura algn objetivo, en la ejecucin de make se
disparar la regla correspondiente (ver seccin 12.3.1). Si en la orden make no gura ningn
objetivo, se disparar la primera regla que gure en el archivo makele.
Para una informacin detallada de las opciones de la orden make consltese la pgina del
manual UNIX correspondiente.
En el resto del captulo describiremos el formato del archivo makele en sus formas ms
simples. La informacin completa sobre el uso de la utilidad make de GNU puede consultarse
en lnea mediante la orden
93
94 12.1. Funcionamiento bsico de make

i nf o make
Para consultar esa documentacin en otros formatos vase [3].
12.1. Funcionamiento bsico de make
La utilidad make funciona basndose en las reglas especicadas en el archivo makele. En
esas reglas se expresa, para cada archivo que deba construirse, de qu otros archivos depende.
Por ejemplo, puede decirse de qu archivos objeto depende un ejecutable que deba construir-
se.
Adems, en esas reglas se expresan las rdenes del shell que deben ejecutarse cuando el
archivo que queremos construir no existe o es ms antiguo que alguno de los archivos de los que
depende (se dice en ese caso que el archivo que necesitamos construir no est al da).
12.2. Sintaxis de los archivos makele
Un archivo makele es un archivo de texto puro, que puede prepararse por tanto con cualquier
editor de texto que permita escribir texto sin formato.
Los archivos makele pueden contener bsicamente comentarios, declaraciones de variables,
reglas que especican las acciones a realizar por make (ver seccin 12.1) y directivas que indican
a make algunas formas especiales de interpretacin del contenido del archivo makele.
En el listado 12.1 puede verse un ejemplo simple del contenido de un archivo makele.
En l pueden verse lneas como la 1 que es un comentario. Cualquier texto que siga la carcter
# hasta el n de lnea se considera un comentario y es ignorado por make.
Las lneas 3 a 8 son deniciones de variables. Por convenio, los nombres de variables se
escriben en maysculas. Los valores de las variables son cadenas de caracteres que siguen al
separador =. Posteriormente a la denicin, puede usarse el valor de la variable en cualquier
expresin que lo requiera mediante la sintaxis $(<nombre_de_variable>). Por ejemplo, en la
lnea 18 se est usando de esa forma el valor de la variable CC de esa manera.
Las lneas 12 a 27 contienen reglas. El contenido esencial de un archivo makele son las
reglas que dirigen la actividad de make.
Cada regla se compone de una lnea de cabecera y de cero o ms acciones que consisten en
rdenes que podrn ser ejecutadas condicionalmente por el shell. Entre cada regla y la siguiente
debe haber al menos una lnea en blanco.
12.3. Sintaxis de las reglas de un archivo makele
El formato genrico de una regla es
12.3. Sintaxis de las reglas de un archivo makele 95
1 # Ejemplo de makef i l e
3 CFLAGS = c ggdb Wall ans i
LNKFLAGS = ggdb Wall ans i
5 CC = gcc
7 OBJS = uno . o dos . o t r e s . o
NOMEXEC = e j e c ut abl e
9
.PHONY : cl ean
11
a l l : $ (NOMEXEC)
13
cl ean :
15 rm f ~ cor e $ (OBJS) $ (NOMEXEC)
17 $ (NOMEXEC) : $ (OBJS)
$ (CC) $ (LNKFLAGS) o $ (NOMEXEC) $ (OBJS)
19
uno . o : uno . c uno . h dos . h
21 $ (CC) $ (CFLAGS) o uno . o uno . c
23 dos . o : dos . c
$ (CC) $ (CFLAGS) o dos . o dos . c
25
t r e s . o : t r e s . c dos . h
27 $ (CC) $ (CFLAGS) o t r e s . o t r e s . c
Listado 12.1: Ejemplo de makele
96 12.4. Ejemplo de ejecucin de la orden make
_

<obj et i vo > : [<pre_requi si to_1> <pre_requi si to_2> . . . ]


[ orden_shel l _1 ]
[ orden_shel l _2 ]
[ . . . ]
La primera lnea es la cabecera de la regla. En ella, <objetivo> es generalmente un nombre
de archivo
1
. Los objetivos de las distintas reglas deben ser todos distintos, de modo que el
objetivo de una regla puede usarse como un identicador para ella. Denotaremos una regla cuyo
objetivo es <objetivo> como Regla(<objetivo>).
Igualmente, los prerrequisitos son nombres de archivos que son opcionales y estn separados
del objetivo por el carcter (obligatorio) : y entre s por espacios en blanco.
Las acciones son lneas que contienen rdenes que posiblemente se pasarn al shell para su
ejecucin cuando se dispare la regla, y deben empezar todas por el carcter <TAB>. En
particular, una lnea que slo contiene el carcter <TAB> no es una lnea en blanco sino una
accin vaca.
12.3.1. Disparo de una regla
Se denomina disparo de una regla a su ejecucin por make.
Denicin: Se dice que un objetivo no est al da si no existe, o bien existe pero su fecha-hora
de modicacin es anterior a la de alguno de sus prerrequisitos.
Las operaciones de disparo de una regla con un objetivo igual a <objetivo> y prerrequisitos
<pre_requisito_1>, <pre_requisito_2>, . . . , se describen en el algoritmo 1:
Algoritmo 1 Disparo de Regla(< objetivo >)
for all < pre_requisito_i > do
if Regla(< pre_requisito_i >) then
Aplicar el algoritmo de disparo a Regla(< pre_requisito_i >)
end if
end for
if < objetivo > no est al da then
Ejecutar las acciones de Regla(< objetivo >)
end if
12.4. Ejemplo de ejecucin de la orden make
Supngase que tenemos en nuestro directorio de trabajo tres archivos fuente en lenguaje C
denominados uno.c, dos.c y tres.c y dos archivos de cabecera denominados uno.h y dos.h
respectivamente. En el texto del archivo uno.c guran dos directivas include del preprocesador
que causan la inclusin de los archivos de cabecera uno.h y dos.h respectivamente, mientras
que en en el archivo tres.c gura una directiva include del preprocesador que causa la inclusin
del archivo de cabecera dos.h.
1
Pero vase el uso de la directiva .PHONY en la seccin 12.4
12.4. Ejemplo de ejecucin de la orden make 97
Si en nuestro directorio de trabajo existe un archivo denominado makefile cuyo contenido
es el texto del listado 12.1, podremos usar la orden make en la forma

make
Los efectos sern los siguientes: Al no usarse la opcin -f se utilizar como makele nuestro
archivo denominado precisamente makefile.
Al no proponerse ningn objetivo en la orden make se disparar la primera regla, que es la
que aparece en la lnea 12 del listado 12.1, y que como puede apreciarse, es una regla sin acciones
asociadas.
Esa regla, una vez sustituidos los valores de las variables que guran en ella, tiene la forma

a l l : e j e c ut abl e
El algoritmo 1 causar que se dispare la regla de las lneas 17-18, puesto que el nico prerre-
quisito de la regla Regla(all) es ejecutable. Una vez sustituidos los valores de las variables
que guran en ella, Regla(ejecutable) tiene la forma
_
`

e j e c ut abl e : uno . o dos . o t r e s . o


gcc ggdb Wall ans i o e j e c ut abl e uno . o dos . o t r e s . o
De acuerdo con el algoritmo 1, debern dispararse las reglas cuyos objetivos son uno.o (lneas
20-21), dos.o (lneas 23-24) y tres.o (lneas 26-27).
La primera de ellas, una vez sustituidos los valores de las variables, tiene la forma
_
`

uno . o : uno . c uno . h dos . h


gcc c ggdb Wall ans i o uno . o uno . c
Los prerrequisitos de esa regla no son objetivos de ninguna otra, as que se comprobar si
uno.o est al da. Si no es as, se ejecutar la accin correspondiente, que, como es evidente
compilar el archivo uno.c para generar uno.o.
Las otras dos reglas dos.o y tres.o funcionan igual, y tienen como nalidad generar los
respectivos archivos objeto a partir de sus fuentes si aquellos no estn al da.
Una vez que se ha hecho esto, uno.o, dos.o y tres.o estarn al da, bien porque ya lo
estaban antes o porque el disparo de las tres reglas habr hecho el trabajo.
Ahora, para terminar de ejecutar el algoritmo de disparo de la regla Regla(ejecutable),
puesto que sus prerrequisitos estn al da, lo que queda por ver es si est al da su objetivo (esto
es el archivo denominado ejecutable).
98 12.4. Ejemplo de ejecucin de la orden make
Figura 12.1: Salida de la orden make para el makele del listado 12.1
Si no es as se ejecutar la accin correspondiente, que, como es evidente, realiza el enlace
de los tres archivos uno.o, dos.o y tres.o para generar el archivo objetivo.
Por ltimo, con la regla Regla(all) no queda nada por hacer, puesto que no tiene acciones
asociadas. Naturalmente, con esta regla se podran haber generado algunos otros ejecutables
ms si la variable NOMEXEC se hubiese denido con un valor que hubiese citado ms nombres de
archivo y no solamente uno.
En la gura 12.1 puede verse la salida en el terminal de la orden make cuando se ejecuta por
primera vez para nuestro ejemplo, supuesto que no hay errores de compilacin ni enlace.
Por otra parte, se comprueba con facilidad que se habrn creado los archivos uno.o, dos.o,
tres.o y ejecutable. Ahora puede comprobarse fcilmente tambin que si cambiamos el con-
tenido de alguno de los archivos fuente, al ejecutar de nuevo make, se recompilarn slo los
archivos necesarios y se realizar de nuevo el enlace. En particular, si no hacemos ningn cam-
bio y ejecutamos make nuevamente, obtendremos un mensaje informndonos de que no hay nada
por hacer con all, esto es, que ejecutable est al da.
Con este archivo makele de ejemplo tambin podemos ejecutar make en la forma siguiente

make cl ean
Si lo hacemos as se disparar la regla cuyo objetivo es clean, que, una vez sustituidos los
valores de las variables, tiene la forma
_
`

cl ean :
rm f ~ cor e uno . o dos . o t r e s . o e j e c ut abl e
12.5. Reglas implcitas 99
Esta regla no tiene prerrequisitos, y su accin se ejecutar por tanto incondicionalmente.
Es evidente que la accin consiste en borrar todos los archivos objeto, ms el ejecutable ms
cualquier volcado de memoria producido por ejecuciones errneas previas (core) y los archivos
que las versiones previas de los archivos de texto que hayan sido modicadas con el procesador
de texto (tpicamente su nombre es el del archivo original terminado con el carcter ).
Ahora resulta claro por qu una regla como sta no debe ser la primera de un archivo makele.
Ello hara que fuera la que se ejecutara cuando usamos make sin argumentos, y eso no es lo que
habitualmente deseamos.
Por otra parte, si no se toman precauciones, la regla Regla(clean) puede dar algunos pro-
blemas. En particular, si existiera un archivo con nombre clean, como no hay prerrequisitos, se
considerara que est al da, y la accin no se ejecutara. Por si se produce esa circunstancia, es
necesario decirle a make que el objetivo clean no es un nombre de archivo, y que la accin de la
regla debe ejecutarse tanto si existe un archivo con ese nombre como si no; de hecho, la accin
tampoco produce un archivo con ese nombre. La forma de hacerlo en la versin GNU de make
es usar la directiva .PHONY tal como se hace en la lnea 10 del listado 12.1.
12.5. Reglas implcitas
En las secciones anteriores hemos descrito la utilizacin de reglas en los archivos makele. Las
reglas que guran en los archivos makele reciben el nombre de reglas explcitas. No obstante, los
diferentes sistemas operativos incorporan utilidades make que disponen de un catlogo de reglas
que aplican implcitamente a falta de reglas explcitas que especiquen cmo debe realizar make
su tarea. Esas reglas implcitas estn asociadas a los nombres de los objetivos y los prerrequisitos
(en particular a las extensiones de los nombres), aplicndose as ciertas reglas para compilar
archivos escritos en determinados lenguajes, mientras que para otros lenguajes se usan otras.
Para una informacin completa sobre el catlogo de reglas implcitas para la versin GNU
de make vase la informacin de manual de la utilidad make en [3] o en la documentacin en
lnea.
Bibliografa
[1] A. Afzal. Introduccin a UNIX. Un enfoque prctico. Prentice Hall, 1997.
[2] Free Software Foundation. BASH reference manual.
http://www.faqs.org/docs/bashman/bashref_toc.html, 2001.
[3] Free Software Foundation. GNU Make Manual. http://www.gnu.org/software/make/manual,
2006.
[4] Indiana University. UNIX command reference card.
http://www.indiana.edu/uitspubs/b017/b017.pdf, 1998.
101

Potrebbero piacerti anche