Sor 030
Sor 030
Sor 030
1
Quick Tour
Inicio de sesión
Conceptos clave
• En Linux, hay que comenzar las sesiones de usuario "iniciando la sesión" en la máquina.
• Para iniciar la sesión se debe contar de antemano con un nombre de usuario y una
contraseña.
• Si una máquina Linux se encuentra ejecutando en un servidor X, los usuarios pueden
iniciar la sesión utilizando la interfaz gráfica.
• Los usuarios pueden iniciar la sesión en cualquiera de las seis consolas virtuales.
• Las teclas CTRL-ALT-F1 hasta CTRL-ALT-F6 realizan el cambio entre las seis consolas
virtuales.
• Las teclas CTRL-ALT-F7 cambian al servidor X predeterminado.
• Si una máquina Linux lo soporta, los usuarios pueden iniciar la sesión en la red utilizando
una shell remota.
• El comando who enumera los usuarios que actualmente tienen una sesión activa y la
manera en que iniciaron la sesión.
Discusión
El sistema operativo Unix, desarrollado originalmente a principios de los años setenta, precede los
días de los computadores personales. Originalmente, muchos usuarios utilizarían Unix de manera
simultánea operando en un computador central. En vez de que cada usuario tuviese un
computador personal, utilizaban lo que se conoce comúnmente (hoy en día) como un"terminal
tonto" - apenas un teclado y un monitor de texto conectados al computador central con una
conexión serial. Para identificarse con el sistema operativo Unix, el usuario tenía que "iniciar
sesión" primero con un userid y su contraseña.
Aunque Linux (y otras versiones de Unix) han crecido para tomar ventaja de los computadores
personales al alcance de todos, no ha perdido los conceptos esenciales como los usuarios, las
contraseñas, el inicio de sesión y las terminales basadas en texto. Esta lección describirá muchas
de las formas para iniciar una sesión interactiva con un sistema Linux.
Consolas virtuales
Red Hat Enterprise Linux proporciona seis "consolas virtuales" disponibles para los usuarios que se
encuentran físicamente frente al computador. Las consolas virtuales actúan como "terminales
tontos". Para acceder a ellas se deben pulsar las teclas desde CTRL-ALT-F1 hasta CTRL-ALT-F6
con una consola virtual asociada a cada una de las primeras teclas de función (si se encuentra en
un entorno gráfico debe recordar que CTRL-ALT-F7, le llevará de regreso a esta consola antes de
intentar cambiar de consola virtual).
Al iniciar una sesión en una máquina Linux utilizando una consola virtual, la pantalla se verá así:
2
Red Hat Enterprise Linux ES release 4 (Nahant)
Kernel 2.6.9-5.EL on an i686
station login:
Para iniciar la sesión, el usuario digita su nombre de usuario sin espacios y pulsa la tecla INTRO.
Después se le pide que escriba la contraseña , la cual no aparece en la pantalla, y luego
pulsaINTRO. Iniciada la sesión, se recibe al usuario con un intérprete de comandos de la shell.
La siguiente parte de este curso tratará de lo que se puede hacer desde el intérprete de comandos
o "prompt" . Por ahora sólo vamos a aprender a terminar una sesión escribiendo el comando "exit"
y pulsandoRETURN. La consola virtual debe regresar a la pantalla original de inicio de sesión.
¿Por qué los usuarios quieren utilizar una consola virtual en vez del entorno gráfico? Primero,
puede que la máquina no tenga suficiente memoria o hardware para soportar el entorno gráfico y
puede que todo lo que se encuentre disponible sean las consolas virtuales. Sin embargo, incluso
en las máquinas modernas, es muy frecuente que las consolas virtuales sean una interfaz más
rápida y más eficaz para los usuarios experimentados. Como son implementadas directamente por
el kernel de Linux, también son útiles en la reparación de sistemas en donde no estén funcionando
los gráficos. Por último, puesto que los servidores de red usualmente pasan la vida encerrados en
armarios, los administradores quieren a menudo evitar la complejidad que la interfaz gráfica le
añade al sistema.
El Entorno Gráfico X
Cuando Linux opera en computadores personales modernos, utiliza un programa de bajo nivel
conocido como el "servidor X" para proveer el entorno gráfico. Como usuario del sistema, usted no
interactúa directamente con el servidor X, sino que proporciona la base para todos los programas
gráficos que ejecuta.
Cuando el servidor X inicia, como parte de la secuencia de inicio del sistema, generalmente busca
la "primera" consola virtual disponible. Debido a que hay seis consolas virtuales para los terminales
de texto, el servidor X usualmente toma la séptima. Si se encuentra en una consola virtual y piensa
que hay un servidor X ejecutando en la máquina, usted puede cambiarse a ésta pulsando las teclas
CTRL-ALT-F7.
3
De nuevo, un usuario inicia la sesión al escribir su nombre de usuario seguido de INTRO y su
contraseña seguida de INTRO.
Figure 2. gnome-terminal
Cuando un usuario termina con el entorno gráfico, este puede salir seleccionando la última opción
del menú de Acciones que está justo a la derecha del menú de Aplicaciones. Esto cerrará todas las
ventanas y regresará el entorno gráfico a su pantalla de inicio original, listo para el siguiente
usuario.
Los usuarios pueden utilizar el comando who para determinar quién se encuentra en el sistema y
cómo iniciaron la sesión. Desde cualquier terminal los usuarios pueden escribir who y presionar la
tecla INTRO. Deben ver una salida similar a la siguiente:
4
La primera columna lista los usuarios que han iniciado sesión y las últimas columnas establecen la
hora en que la iniciaron. Con un poco de experiencia, la segunda columna le dice el lugar en donde
el usuario inició la sesión. Para los primeros dos usuarios, elvis y root, tty1 y tty2 se refiere a las
consolas virtuales 1 y 2 respectivamente. La primera entrada para blondie, :0, se refiere al servidor
X mismo y pts/0 se refiere a la primera terminal abierta en el servidor X. Sin detenernos mucho en
los detalles, podemos ver que elvis ha iniciado sesión en la segunda consola virtual, root en la
primera y blondie ha iniciado sesión utilizando el entorno gráfico.
Al utilizar la opción ssh ("secure shell"), los usuarios pueden iniciar una sesión fácilmente en
máquinas remotas ya sea en el mismo lugar o al otro lado del mundo. Asumiendo que la máquina
remota se encuentra configurada para permitir el inicio de sesión de manera remota y que el
usuario tiene una cuenta en la máquina, el iniciar una sesión en una máquina remota puede ser tan
fácil como iniciar una sesión en una consola virtual. En el siguiente ejemplo, elvis iniciará una
sesión en una consola virtual en la máquina local llamada station.redhat.com. Después utilizará
ssh para iniciar la sesión en una máquina remota nimbus.example.com, muy posiblemente al otro
lado del mundo.
Preste mucha atención al intérprete de comandos en el siguiente ejemplo. Como con frecuencia los
usuarios de Linux van "saltando" de máquina en máquina utilizando shells remotas, el intérprete de
comandos ha sido diseñado para ayudar al usuario a recordar en qué máquina está operando la
shell.
Observe que cuando elvis ejecutó el comando who en la máquina remota, ésta reportó la máquina
desde donde inició la sesión llamada station.redhat.com.
Hay clientes ssh para sistemas operativos diferentes de Linux. Por ejemplo, la aplicación Open
Source PuTTY se puede instalar en casi cualquier máquina windows y se puede utilizar para abrir
un intérprete de comandos en un servidor Linux remoto.
5
Ejemplos
En el siguiente ejemplo, un usuario inicia sesión en la primera consola virtual como el usuario elvis,
pero luego se da cuenta de que su sistema se encuentra mal configurado. Para poder arreglar
esto, va a cambiar a la segunda consola virtual e iniciará sesión como root y arreglará el problema.
Luego saldrá y regresará a la primera consola virtual listo para iniciar.
En este momento, elvis ha tratado de leer el archivo /tmp/README, pero los permisos del archivo
no le permitieron hacerlo. Debido a que el usuario conoce la contraseña para la cuenta de root (del
administrador) en la máquina, puede arreglar el problema cambiándose a otra consola virtual
(utilizando las teclas CTRL-ALT-F2), iniciando sesión como root y cambiando los permisos del
archivo.
Observe que la salida del comando who muestra que el usuario inició sesión como elvis en la
primera consola virtual e inició sesión como root en la segunda. El usuario ahora cambia de vuelta
a la primera consola virtual utilizando CTRL-ALT-F1 y reanuda la sesión.
6
El kernel, los programas y los procesos
Conceptos clave
Discussion
El kernel de Linux
El kernel de Linux es un sistema operativo así como Windows, MacOS y OS/2. El sistema
operativo es un entorno en el cual se ejecuta un programa. proporcionándole los mecanismos a los
programas para interactuar con el hardware del computador. El kernel le permite saber a un
programa cuándo se pulsa una tecla, cuándo se mueve el ratón o cuándo llegó un paquete
destinado para el programa a través de la red . El kernel le permite a los programas acceder al
disco duro, quizás para leer los archivos de configuración o almacenar datos.
Así como sería difícil explicar lo que es un lenguaje a una persona que ha crecido con el
conocimiento de un solo idioma, con frecuencia es difícil explicar lo que es un sistema operativo a
aquellas personas nuevas en el área de los computadores o a aquellos que solamente han
utilizado un sistema operativo. El sistema operativo funciona en un nivel tan bajo que los usuarios
no interactúan con éste directamente y a menudo no se dan cuenta de que los programas que se
encuentran ejecutando lo están utilizando.
Los programas
Los programas son archivos almacenados en el disco duro de un computador. Un programa es una
serie de instrucciones básicas que le indican al sistema operativo qué hacer y cuándo hacerlo de
una manera bastante detallada y específica. Las siguientes pueden ser las instrucciones escritas
en el archivo /usr/X11R6/bin/xcalc, un programa común de calculadora.
7
"Mientras que el usuario no esté haciendo nada, el cursor titila. Cuando el usuario pulsa una tecla,
si es un número, lo escribe en la pantalla. Si no es un número lo ignora, a menos que sea la tecla
intro. Si es la tecla intro, añade el número anterior al total y muestra el total."
Claro está que las instrucciones no se encuentran en inglés ni en ningún otro lenguaje humano. En
cambio, un computador en el nivel más bajo sólo sabe cómo realizar un pequeño número de
tareas, digamos 256 de ellas. Imagine que cada una de esas tareas estuviesen numeradas de 0 a
255. Los programas se ven en realidad más como las siguientes instrucciones:
"Realice la tarea 23. Si el resultado es mayor que 0, entonces haga la tarea 45. De otra forma,
complete la tarea 82. Tome el resultado y almacénelo en la memoria."
Debido a que las tareas que un computador puede llevar a cabo varían dependiendo del tipo de
CPU, y que diferentes sistemas operativos podrían listar las tareas de forma diferente, los
programas compilados para un tipo de sistema operativo, por lo general, no ejecutarán en otros
sistemas operativos.
Los procesos
Cuando un usuario le pide al kernel que ejecute un programa, el kernel lee las instrucciones que se
encuentran en el el archivo del programa y las carga en la memoria. Después empieza a llevar a
cabo las instrucciones . La copia del programa ejecutando en la memoria se denomina un proceso.
Observe que el mismo programa se puede cargar en la memoria y se puede ejecutar más de una
vez para que en cualquier momento el kernel pueda ejecutar varios procesos del mismo programa.
Las shells
Los usuarios de Linux con frecuencia utilizan un tipo especial de programa llamado shell para
interactuar con el kernel. La shell ejecuta dentro de una terminal emitiendo un "prompt"y esperando
a que le digan qué hacer. Luego, el usuario le pide a la shell que ejecute un programa escribiendo
el nombre del programa. En el siguiente ejemplo, el usuario elvis le pide a la shell que ejecute un
programa sencillo de calendario llamado cal. La shell ejecuta obedientemente el programa y
reporta la salida del programa a la terminal:
8
18 19 20 21 22 23 24
25 26 27 28 29 30 31
[elvis@station elvis]$
Debido a que los usuarios utilizan una shell para llevar a cabo casi todas las tareas en el sistema,
la shell es un programa importante y sofisticado. Gran parte de este curso se dedicará a aprender a
utilizar la shell para realizar tareas de manera efectiva.
Cuando el usuario le pide a la shell que ejecute un programa, se dice que el usuario está
especificando un comando para la shell. Con frecuencia la shell se conoce como la interfaz de
línea de comandos.
El comando ps
[elvis@station elvis]$ ps
PID TTY TIME CMD
1378 pts/1 00:00:00 bash
1418 pts/1 00:00:00 ps
La primera columna muestra el id del proceso (PID del inglés Process ID). Todo proceso
ejecutándose en el sistema se identifica con un ID de proceso único. La segunda columna identifica
la terminal de elvis y la tercera reporta el tiempo de CPU que el proceso ha utilizado.
El comando ps aux muestra una lista detallada de todos los procesos ejecutándose en el sistema.
Por ahora no explicaremos lo que significa "aux", sólo piense que es como un acto de magia negra
que debe memorizar. Tampoco le explicaremos todos los campos, todo esto se discutirá en el
siguiente cuaderno. Simplemente observe que en cualquier momento hay, por lo general, un gran
número de procesos ejecutándose en un sistema Linux (note que en la siguiente salida se han
eliminado bastantes líneas y se han reemplazado con "...").
9
[elvis@station elvis]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 1388 460 ? S 18:52 0:04 init [
root 2 0.0 0.0 0 0 ? SW 18:52 0:00 [keventd]
...
root 548 0.0 0.2 1460 580 ? S 18:53 0:00 syslogd -m 0
root 552 0.0 0.1 1384 428 ? S 18:53 0:00 klogd -x
rpc 570 0.0 0.2 1560 552 ? S 18:53 0:00 portmap
root 622 0.0 0.2 1496 632 ? S 18:53 0:00 /sbin/cardmgr
root 628 0.0 0.0 0 0 ? SW 18:53 0:00 [kapmd]
root 633 0.0 0.1 1380 484 ? S 18:53 0:00 /usr/sbin/apmd -p
root 644 0.0 0.5 3524 1512 ? S 18:53 0:00 /usr/sbin/sshd
root 655 0.0 0.3 2040 860 ? S 18:53 0:00 xinetd -stayalive
root 674 0.0 0.9 6204 2504 ? S 18:53 0:00 sendmail: accepti
smmsp 683 0.0 0.8 6004 2256 ? S 18:53 0:00 sendmail: Queue r
root 693 0.0 0.1 1424 444 ? S 18:53 0:00 gpm -t ps/2 -m /d
root 702 0.0 0.2 1580 672 ? S 18:53 0:00 crond
xfs 781 0.0 1.5 5272 4004 ? S 18:53 0:00 xfs -droppriv -da
root 800 0.0 0.2 3416 544 ? S 18:53 0:00 rhnsd --interval
root 807 0.0 0.1 1364 396 tty1 S 18:53 0:00 /sbin/mingetty tt
...
root 1375 0.0 0.3 4120 968 pts/1 S 20:11 0:00 su - elvis
elvis 1378 0.0 0.5 4324 1404 pts/1 S 20:11 0:00 -bash
elvis 1438 0.0 0.2 2648 696 pts/1 R 20:30 0:00 ps aux
El sistema de archivos
Conceptos clave
• La base del árbol de directorios de Linux es un directorio llamado / y conocido como el"
directorio root".
• Las referencias absolutas de archivos, tales como /home/elvis/lsout.txt, se refieren a los
archivos relativos al directorio raíz.
• Las referencias relativas de archivo, tales como lsout.txt, hacen referencia a archivos
relativos al directorio de trabajo actual de un proceso.
• El comando ls se utiliza para enumerar el contenido de un directorio.
• El comando cat se utiliza para examinar el contenido de un archivo.
• Al utilizar el caracter > desde la línea de comandos de la shell, la salida de un comando
puede redireccionarse desde la terminal a un archivo.
• El directorio home es uno de los pocos lugares en donde los usuarios pueden crear
archivos nuevos.
Discusión
En Linux,la información y los programas se encuentran almacenados en discos como archivos. Los
archivos se encuentran agrupados en los directorios, los cuales pueden contener archivos y otros
directorios (otros sistemas operativos con frecuencia se refieren a directorios como "carpetas").
10
Esta jerarquía de directorios que contienen directorios se conoce a menudo como el "árbol de
directorios".
La base del árbol de directorios es un directorio llamado simplemente / y se conoce como "el
directorio raíz". Los archivos dentro del directorio raíz se conocen como /nombre del archivo. En
Red Hat Enterprise Linux, el directorio raíz contiene principalmente otros directorios tales como
/etc. Los archivos dentro de estos subdirectorios se conocen como /etc/nombre del archivo y el
proceso continúa así para cada nuevo nivel de subdirectorios. Por ejemplo, el archivo network que
se encuentra en el directorio sysconfig, que a su vez se encuentra en el directorio etc, el cual está
en el directorio root /, puede conocerse como /etc/sysconfig/network.
Obviamente, el iniciar en el directorio raíz cada vez que se refiera a un archivo es bastante trabajo.
Afortunadamente, Linux proporciona una manera más fácil. Todo proceso, incluyendo la shell de un
usuario, utiliza un "directorio actual de trabajo" por contexto. Los archivos en un directorio actual de
trabajo se conocen simplemente como nombre de archivo, sin la barra oblicua inicial. Los archivos
en los subdirectorios del directorio actual de trabajo se conocen como nombre del
directorio/nombre del arhivo, de nuevo sin la barra oblicua inicial. Por ejemplo, si el directorio actual
de trabajo de un proceso fuese /etc, el archivo network mencionado anteriormente se conocería
como sysconfig/network. Si el directorio de trabajo fuese /etc/sysconfig entonces el archivo podría
ser simplemente network.
En resumen, siempre hay dos maneras de referirse a un archivo. Las referencias de archivo
relativas al directorio raíz, siempre comienzan con una barra oblicua inicial / y se llaman referencias
absolutas absolute. Las referencias de un archivo relativas al directorio de trabajo actual
comienzan con cualquier cosa que no sea una / y se conocen como referencias relativas.
Desde una shell los usuarios pueden utilizar el comando ls para hacer un listado del contenido de
un directorio (imagínese que ls es la forma corta para la palabra "lista"). En el siguiente ejemplo, el
usuario elvis quiere hacer una lista del contenido del directorio /etc/sysconfig/rhn.
El comando ls, cuando se emite sin ningún argumento (por ejemplo, sin especificar un directorio)
lista el contenido del directorio de trabajo actual de la shell. Si utiliza una terminal con colores,el
comando ls también le pone color a los nombres de los directorios para ayudar a distinguir el
contenido de los directorios que tienen archivos comunes (en blanco) y los que son directorios (en
azul).
El ls es un comando muy flexible que puede proporcionar mucha información. Este se estudiará en
más detalle en lecciones posteriores.
Mientras el comando ls lista los archivos que se encuentran en un directorio dado, éste no revela el
contenido de los archivos. Aunque hay varios comandos disponibles para ver los archivos, el
comando más sencillo es cat. Cuando se le da una lista de archivos al comando cat este
concatena los archivos a la salida del terminal. Si sólo se le da el nombre de un archivo entonces
mostrará el contenido de solo ese archivo.
11
En el siguiente ejemplo, el usuario elvis quiere ver el contenido del archivo de configuración
/etc/hosts.
Por ahora, no se preocupe de lo que significa el contenido, sólo tenga en cuenta que el comando
cat presenta todo el contenido de este archivo de cinco líneas.
Observe que si le pide a cat que presente un archivo muy largo o un archivo binario (no texto), cat
lo hará obedientemente. Hay comandos más sofisticados para ver archivos largos, una pantalla a
la vez, lo cual se verá más adelante.
En el siguiente ejemplo, el usuario elvis de nuevo va a hacer una lista del contenido del directorio
/etc/sysconfig/rhn, pero quiere redireccionar la salida a un archivo recién creado.
Observe lo que pasa cuando elvis trata de redireccionar la salida a un archivo que se encuentra en
un lugar diferente al directorio actual de trabajo de la shell.
12
[elvis@station elvis]$ ls /etc/sysconfig/rhn > /etc/lsout.txt
-bash: /etc/lsout.txt: No such file or directory
El usuario elvis se ha encontrado con otro concepto común en Linux: propiedad y permisos de un
archivo. El usuario elvis trató de crear el nuevo archivo /etc/lsout.txt, pero elvis no tiene el permiso
para crear archivos en el directorio /etc.
Por defecto, en Red Hat Enterprise Linux, los usuarios no pueden crear archivos en cualquier lugar.
De hecho, sólo hay unos pocos lugares en donde se pueden crear archivos. Todo usuario tiene un
directorio de inicio, en donde puede crear nuevos archivos (y nuevos subdirectorios).
Afortunadamente, cuando los usuarios inician una sesión en Linux, su shell utiliza su directorio
inicial como su directorio actual de trabajo. Por defecto en Red Hat Enterprise Linux, el directorio
inicial de un usuario se llama /home/username, dondeusername se reempla con el nombre del
nombre del usuario.
Otros cuaderno abordarán el sistema de archivos y los permisos en mucho más detalle. Por ahora,
sólo tenga en cuenta que a los usuarios, generalmente, sólo se les permite crear archivos en su
directorio de inicio.
Ejemplos
El usuario prince quiere utilizar el comando cal para almacenar un calendario del mes actual en el
archivo calendar.txt.
[prince@station prince]$ ls
calendar.txt
13
prince primero ve la salida del comando cal directamente.
prince ejecuta otra vez el comando cal redireccionando la salida al archivo calendar.txt
prince confirma que el nuevo archivo ha sido creado listando el contenido de su directorio de
trabajo actual (en este caso su directorio de inicio).
prince examina el contenido del nuevo archivo para confirmar que contiene la salida del comando
cal.
Ejecución de comandos
Conceptos clave
• Como cualquier otro idioma la shell bash utiliza una gramática específica.
• La primera palabra en cualquier línea de comandos es el nombre del programa que se va a
ejecutar.
• El comportamiento de los comandos se puede modificar con las opciones de la línea de
comandos (usualmente opcional), las cuales siempre empiezan con uno o dos guiones (- o
--).
• Las palabras u opciones que siguen después del comando se llaman argumentos del
comando arguments
• Algunas opciones de la línea de comandos también toman argumentos.
• Los comandos usualmente soportan las opciones --help, -h o -?, las cuales presentan un
resumen de cómo utilizar el comando.
Discussion
Si los comandos que se introducen en la línea de comandos se comparan con las oraciones en
inglés entonces los comandos tienen verbos, adverbios y objetos directos. El verbo es el comando
a ejecutar, los adverbios son las diferentes opciones que se pueden utilizar para modificar el
comportamiento del comando (“calmadamente” o “con fluidez”) y las palabras que quedan son los
objetos directos (sobre lo que el comando debe actuar). Además, así como en los idiomas, hay
irregularidades y para casi toda regla mencionada habrá excepciones.
Comandos
14
/usr/bin/who
Cuando se ejecuta un comando, el proceso de la shell le pide al kernel que ejecute el programa
especificado como un proceso separado y hace que la salida (o mejor, la salida estándar) del
proceso se escriba en la terminal. Entonces la shell realiza una pausa hasta que el proceso del
comando termina. Una vez el comando termina, la shell presenta otro intérprete de comandos y
espera a que se le diga que hacer.
El primer comando ls simplemente hace una lista del contenido del directorio. El segundo comando
ls -s, el cual incluye la opción -s, presenta también el tamaño del contenido también. El tercer
comando ls -l presenta una lista "larga", incluyendo todo tipo de detalles sobre los archivos tales
como los permisos, propiedad y la fecha de modificación. Por ahora, no se preocupe de los detalles
en la salida, ésto se abarcará en un cuaderno posterior sobre la utilización del sistema de archivos.
Sólo observe cómo se utilizan las opciones de la línea de comandos para modificar el
comportamiento básico del comando ls.
Observe que las dos opciones que se utilizaron anteriormente -s y -l son opciones de una sola
letra. Estas se conocen como opciones "cortas" de la línea de comandos. A veces estas opciones
15
cortas también pueden tener un argumento. Por ejemplo, el comando ls tiene la opción -w, la cual
especifica la "extensión", de la salida en caracteres. Considere el siguiente ejemplo:
Se puede utilizar más de una opción de la línea de comandos a la vez. Las múltiples opciones
simplemente se ponen juntas entre el comando y el argumento. El siguiente ejemplo presenta una
nueva opción -r para el comando ls, el cual invierte el orden de búsqueda. Observe cómo se utiliza
junto con las opciones -s y -w.
Con frecuencia, cuando se utilizan múltiples opciones, los usuarios tomarán ventaja del atajo que
les permite poner todas las opciones juntas con un sólo guión (-), como en el siguiente ejemplo:
Todas las opciones con letras individuales que no tienen argumento, en este caso -s y -r, se
pueden poner juntas compartiendo un solo -. Si una opción sí tiene argumento tal como -w 40, sólo
puede compartir un guión si está de última. De esta manera, se puede especificar el argumento
justo al lado de la línea de comandos.
En los primeros días de Unix, todas las opciones de la línea de comandos compartían la sintaxis
mencionada anteriormente. Con la evolución de Unix, la gente empezó a necesitar lo que se
conoce como opciones "largas". A diferencia de las opciones con sólo una letra, las opciones
largas están compuestas de palabras. En vez de empezar con un guión inicial, las opciones largas
16
están precedidas de dos guiones (--). Algunos comandos utilizan sólo opciones cortas y algunos
comandos utilizan opciones largas. Muchos comandos, incluyendo ls, manejan ambos.
Cuando las opciones largas tienen un argumento, la sintaxis también difiere un poco. En vez de
que el argumento siga la opción como una palabra separada, el argumento se pone junto con la
opción larga separada por un =, como en --width=40. Observe que las opciones tanto largas como
cortas, también se pueden mezclar.
Argumentos
Comparados con las opciones de la línea de comandos, los argumentos son fáciles. Cualquier
palabra que quede en la línea de comandos, después del nombre del comando y después de
cualquier opción de la línea de comandos se le denomina argumentos del comando. Lo que el
comando espera o no como argumento depende del comando. Por ejemplo, si se le da algún
argumento al comando ls el comando tratará los argumentos como archivos o directorios a
enumerar. El comando ps no espera ningún argumento. El comando cal toma de cero a dos, un
mes y un año posibles para poder generar el calendario. El aprender qué argumentos espera un
programa y lo que hace con estos es parte del aprender a utilizar ese comando.
Ayuda: uso
¿Cómo recordar todas estas opciones de la línea de comandos? No es necesario. No obstante, los
usuarios experimentados de Linux han aprendido a refrescar fácilmente su memoria ya que la
mayoría de los comandos soportan la opción --help o las opciones cortas -h o -?. Estas opciones
usualmente hacen que el comando emita un mensaje de "uso" en vez de realizar su operación
normal. Este mensaje de uso contiene un resumen de los argumentos que se esperan, las
opciones que se soportan y lo que hacen. Observe que el mensaje de uso generado por el
comando ls es bastante largo y ha sido abreviado en la siguiente salida.
17
Mandatory arguments to long options are mandatory for short options too.
-a, --all do not hide entries starting with .
-A, --almost-all do not list implied . and ..
--author print the author of each file
-b, --escape print octal escapes for non-graphic characters
...
-k like --block-size=1K
-l use a long listing format
...
...
-v sort by version
...
Los mensajes de uso no proporcionan una referencia completa para el comando, sino que
simplemente proporcionan información para refrescar la memoria. Más adelante en este cuaderno
se discutirán otras formas de encontrar ayuda.
18
Ejemplos
Una amiga del usuario madonna le dijo que el comando cat se utiliza para mirar el contenido de los
archivos. Ella nunca ha utilizado este comando antes y está interesada en aprender a utilizarlo.
Entonces, empieza por examinar el mensaje de uso del comando.
Todavía no entiende todo el mensaje de uso, como por ejemplo, las referencias a la entrada y a la
salida estándar, pero puede entender lo suficiente de la primera línea como para comprender que
el comando cat espera los nombres de archivo como su argumento. Intenta mostrar el contenido
del archivo /etc/anacrontab.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
Al ver algunas de las opciones de los mensajes de uso observa que la opción -n numera las líneas
de salida y decide probar esta opción:
19
[madonna@station madonna]$ cat -n /etc/anacrontab
1 # /etc/anacrontab: configuration file for anacron
2
3 # See anacron(8) and anacrontab(5) for details.
4
5 SHELL=/bin/sh
6 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
7
8 1 65 cron.daily run-parts /etc/cron.daily
9 7 70 cron.weekly run-parts
/etc/cron.weekly
10 30 75 cron.monthly run-parts
/etc/cron.monthly
4 X11R6 0 local 4 games
0 tmp 4 libexec 4 etc
4 src 40 lib 4 dict
8 share 4 kerberos 40 bin
8 sbin 8 include
Desde la salida ahora es fácil ver que este archivo tiene 10 líneas y es fácil referirse a la línea 6.
Sospecha que el espacio que hay entre las palabras desde el renglón 8 hasta el 10 son efecto del
tabulador en vez del espaciador. Al observar del mensaje de uso que la opción -t reemplazará
cualquier espacio del tabulador con ^I, intenta confirmar su sospecha.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
1^I65^Icron.daily^I^Irun-parts /etc/cron.daily
7^I70^Icron.weekly^I^Irun-parts /etc/cron.weekly
30^I75^Icron.monthly^I^Irun-parts /etc/cron.monthly
Ahora observa que el uso de la opción -A es "equivalente a -vET", el cual ella asume que es el
atajo de la opción corta -v, -E y -T. Prueba ambos para ver si está en lo correcto.
20
# See anacron(8) and anacrontab(5) for details.$
$
SHELL=/bin/sh$
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin$
$
1^I65^Icron.daily^I^Irun-parts /etc/cron.daily$
7^I70^Icron.weekly^I^Irun-parts /etc/cron.weekly$
30^I75^Icron.monthly^I^Irun-parts /etc/cron.monthly$
Al ver que las salidas son idénticas, decide que ha interpretado correctamente el mensaje de uso.
Administración de terminales
Conceptos clave
• Varias secuencias de control tales como CTRL-C, CTRL-D y CTRL-Z pueden ser útiles
para administrar procesos desde la terminal.
• La configuración de una terminal puede ser devuelta a su estado inicial con el comando
reset.
• La shell bash ofrece la oportunidad de completar con el tabulador, la cual le puede ahorrar
bastante tiempo al escribir especificando comandos o archivos.
• Se pueden distinguir varios tipos de terminales al saber cómo se refiere Linux a los
dispositivos.
Discussion
Control de terminales
La shell bash y el terminal en que ejecuta son las herramientas principales que los usuarios
experimentados de Linux utilizan. Más adelante en este curso se dedicará un cuaderno completo a
la manera de utilizar las potentes características de la shell de bash. Esta lección introduce
algunas carcterísticas que las terminales comparten en general y una de ellas que no debería
dejarse para más tarde: el completar con el tabulador.
Reinicio de terminales
Cuando las terminales presentan información, muestran un byte a la vez. Cuando los
computadores manejan texto humano, los caracteres usualmente se encuentran codificados como
un valor de bytes en números enteros utilizando el formato ASCII. Mientras que un byte puede
codificar hasta 256 valores diferentes, sólo se utiliza un pequeño número de éstos (alrededor de
100) para caracteres de texto y puntuación. Los otros se utilizan para codificar secuencias de
control (vea a continuación) y otras condiciones especiales.
A veces los usuarios accidentalmente (o intencionalmente) le piden a una terminal que presente
datos no codificados como texto ASCII, como por ejemplo, una imagen o un ejecutable. La terminal
hace lo mejor que puede, pero con frecuencia presenta lo que parecen ser simplemente garabatos.
Incluso la terminal puede terminar en un modo alterno de gráficos para que inclusive se vea mal lo
que se debe ver como texto ASCII normal.
En estas situaciones, el comando reset puede restablecer la terminal a una conducta cuerda.
Usualmente, cuando quiere utilizar este comando ni siquiera podrá ver al escribirlo. Sin embargo, si
21
tiene un intérprete de comandos bash con caracteres incomprensibles, al escribir reset seguido de
la tecla INTRO usualmente la terminal se restaurará a una conducta cuerda.
Los terminales Linux comparten bastante con sus ancestros primitivos, los teletipos y las consolas
"tontas" o las similares a vt100. Estos dispositivos tenían mecanismos para enviar señales "fuera
de banda" o secuencias que señalaban un evento fuera del flujo normal de caracteres escritos
tales como un espacio, una campanilla audible o un final de transmisión. Las terminales de Linux,
como sus predecesores, utilizan la tecla CTRL para enviar esas señales "fuera de banda".
La siguiente tabla resume muchas de las secuencias de control utilizadas con frecuencia que todos
los terminales Linux comparten y su uso común en orden alfabético. Después de la tabla se
discuten estas secuencias de acuerdo con su utilidad en general.
CTRL-C es probablemente una de las secuencias más útiles mencionadas anteriormente. Ésta
llega al rescate cada vez que un usuario siente que "SOLO QUIERO QUE SE DETENGA". Al
utilizar la shell bash, escribiendo CTRL-Cterminará el proceso que se está ejecutando en ese
momento y lo devolverá al intérprete de comandos bash.
El nodo de dispositivo /dev/zero es un pseudo dispositivo que cuando se lee devuelve un número
infinito de ceros (binarios). El nodo del dispositivo /dev/null es un pseudo dispositivo que bota
cualquier información escrita en él. Por lo tanto, el siguiente comando ejecutaría por siempre
leyendo y botando ceros. Alguien atascado en esta situación podría utilizar CTRL-C para cancelar
el comando.
CTRL-D
22
Como lo verá en un cuaderno posterior muchos de los comandos Unix leen su entrada
directamente del teclado. Infortunadamente, para los nuevos usuarios Unix, no siempre es
obvio el cómo decirle al comando que pare de escuchar. La respuesta es CTRL-D. Esta
secuencia se utiliza para enviar un mensaje de "Fin de la Transmisión" (usualmente
interpretado como "Final del Archivo") al proceso de escucha.
[elvis@station elvis]$ wc
polly wants a cracker
polly wants a cracker
polly wants a cracker
(... user types CTRL-D ...)
3 12 66
[elvis@station elvis]$
CTRL-Z
23
226 Directory send OK.
...
CTRL-U
CTRL-U usualmente se utiliza para "limpiar" la línea actual. Si ha cambiado tanto una línea
de comandos bash y sólo quiere volver a empezar en limpio pulse CTRL-U. También,
CTRL-U es muy útil cuando cometa errores al ingresar una contraseña. Como los
caracteres usualmente no aparecen en la pantalla, es difícil saber lo que ha escrito. Sólo
pulse CTRL-U e inicie de nuevo.
CTRL-H
CTRL-H tiene la misma función que la TECLA DE RETROCESO. Sin embargo, en algunas
terminales laTECLA DE RETROCESO se encuentra mapeada de manera incorrecta y por
lo tanto no funciona bien. CTRL-H casi siempre funcionará en estas situaciones.
CTRL-L
La shell bash, CTRL-L hace que bash deje en limpio la pantalla, pero preserva la línea de
comandos actual.
CTRL-Q
CTRL-Q "descongela" una pantalla (haciendo que se active de nuevo) después de que se
ha "congelado" con CTRL-S. Aunque sólo es útil después de haber utilizado CTRL-S, se
introduce primero (como el comando más útil) ya que nadie utiliza intencionalmente CTRL-
S. Por el contrario, los nuevos usuarios de Unix a veces pulsarán por error CTRL-S y no
entenderán el porqué su terminal no responde. Si alguna vez su terminal parece muerta,
intente presionar CTRL-Q y vea si eso la arregla.
CTRL-S
CTRL-J
CTRL-G
24
El único uso real es que hace pitar la terminal, impresionando a sus amigos con su basta
reserva de conocimiento inútil sobre Unix.
Identificación de terminales
Así como con la mayoría de los otros dispositivos, los programas interactúan con los terminales en
un nivel bajo por medio de nodos de dispositivos, que se encuentran dentro del directorio /dev. Por
ejemplo, la comunicación con la primera consola virtual utiliza el nodo de dispositivo /dev/tty1. La
mayoría de los procesos mantienen un registro de la terminal en donde empezaron y las sesiones
de inicio de los usuarios usualmente se encuentran asociadas con la terminal que se encuentran
utilizando. Al identificar las terminales en estas situaciones, la terminal se conoce por medio de su
nodo de dispositivo, por ejemplo, tty1.
En el siguiente extracto, elvis hace una lista de los usuarios actuales en una máquina con who y
enumera los procesos ejecutándose en ese momento desde su terminal con ps. En ambos casos
el terminal es especificado en la columna "TTY".
Linux trata muchos dispositivos diferentes como una terminal, incluyendo las consolas virtuales,
una línea en serie conectada a terminales VT100, módems, etc. La siguiente tabla lista algunos de
los nombres comunes para terminales utilizados convencionalmente para algunos de los
dispositivos de terminal comúnes.
25
Completar con el tabulador
Completar con el tabulador no es una característica de las terminales sino de la shell bash que
usualmente ejecuta dentro de éstas. Se puede ahorrar bastante tiempo y esfuerzo aprendiendo a
hacer buen uso del tabulador al escribir los nombres de los comandos y archivos.
Al escribir el nombre de un comando como la primera palabra de una línea de comandos bash,
comience a escribir el comando que quiera ejecutar, pero en algún momento antes de que termine
la palabra, pare y pulse la tecla del TABULADOR. Puede pasar una de tres cosas:
La shell bash hace lo mejor que puede seleccionando el comando que usted empezó a escribir de
la lista de todos los comandos posibles. En el primer caso, sólo hay un comando que comienza con
las letras que usted escribió así que bash puede descubrir exactamente el comando que usted
había empezado y lo termina de escribir por usted. Ha terminado.
En el segundo y tercer caso, más de un comando inicia con las letras que usted escribió. bash
completó el comando tanto como pudo pero paró y le pitó para dejarle saber que usted aún tiene
que escoger. Para poder ver las opciones de los comandos que bash ha delimitado, oprima el
tabulador dos veces y bash hará una lista de todos los comandos que inician con las letras que
usted escribió inicialmente. Proporcione lo suficiente del comando para que sea único y oprima el
tabulador de nuevo. bash terminará de escribir el comando por usted.
Un ejemplo es en orden.
El usuario elvis quiere habilitar el modo Unicode para su terminal. Por ahora no se preocupe de lo
que es el modo Unicode o el por qué quiere tenerlo. Sólo necesita saber que el comando que
habilita este modo se llama unicode_start y el comando que lo desactiva es unicode_stop.
Empieza a escribir el comando y presiona el tabulador.
bash expande la palabra a unicode_st y pita. Para poder ver la lista de opciones disponibles para
completar, elvis teclea el tabulador dos veces.
bash le devuelve una lista con dos opciones posibles que enmpiezan con unicode_st. Al ver que
el comando que elvis quiere ejecutar es el único que empieza con unicode_sta, elvis escribe una a
y presiona el tabulador.
26
[elvis@station elvis]$ unicode_sta<TAB>
bash completa el comando y pone el cursor para que esté listo para comenzar a escribir cualquier
argumento u opciones para el comando.
bash no sólo completa la primera palabra al compararla con los comandos disponibles sino que
también se pueden completar las otras palabras en la línea de comandos con base en el sistema
de archivos. Por ejemplo, suponga que madonna quiere examinar el archivo /etc/prelink.conf. En
vez de tener que escribir el nombre completo del archivo, ella puede escribir la primera parte y
después presionar el tabulador.
Debido a que /etc/prelink.conf es el único archivo que inica con /etc/prel, bash puede completar
todo el archivo.
Ejemplos
El usuario blondie accidentalmente utiliza el comando cat para ver un archivo ejecutable, /bin/arch.
Como el archivo es un ejecutable compilado, contiene bytes que no se pueden mostrar en una
terminal y esto la descontrola.
27
Para restablecer la terminal, blondie escribe el comando reset a ciegas y su terminal se
restablece.
[blondie@station blondie]$
Cancelar un comando
El usuario prince piensa que puede ser interesante el listar recursivamente el contenido de su
sistema de archivos, iniciando con el directorio raíz /.
[prince@station prince]$ ls -R /
/:
bin data etc initrd lost+found mnt proc root sbin usr web
boot dev home lib misc opt rha RPMS tmp var
/bin:
arch cut gawk mail rm touch
ash date gettext mkdir rmdir true
ash.static dd grep mknod rpm umount
aumix-minimal df gtar mktemp rvi uname
awk dmesg gunzip more rview unicode_start
basename dnsdomainname gzip mount sed unicode_stop
bash doexec hostname mt setfont unlink
bash2 domainname igawk mv setserial usleep
Después de ver pasar los archivos por varios minutos, considera que ha visto lo suficiente. Cancela
el comando presionando CTRL-C. El comando termina y regresa al intérprete de comandos bash.
[prince@station prince]$
Suspender la salida de una terminal Lab Exercise Objetivo: Aprender a administrar la salida de la
terminal para aquellos comandos con una ejecución larga.Tiempo estimado: 5 minutos.
Especificaciones
1. Como en el ejemplo de prince, tome una lista recursiva del directorio root del sistema de
archivos utilizando el comando ls -R /.
2. Mientras que esté apareciendo la salida, congele su terminal utilizando la secuencia CTRL-
S.
3. Descongele la terminal utilizando la secuencia CTRL-Q. Debería poder alternar el
congelamiento y descongelamiento de la salida utilizando estas secuencias.
4. Mientras que la salida aún se encuentre fluyendo, suspenda el proceso con la secuencia
CTRL-Z.
5. Confirme que ha suspendido el proceso.
28
1 El comando suspendido ls -R /
Limpieza
29
Getting Help
Conceptos clave
• La mayoría de los comandos proporcionan resúmenes cuando se invocan las opciones -h,
-? o --help.
• Puede encontrar información de referencia mucho más amplia en las "páginas del manual",
las cuales se pueden ver con el comando man.
• Las páginas man tienen capítulos y el contenido de un capítulo anterior puede llegar a
obscurecer el contenido de un capítulo en desarrollo.
• Los comandos más complicados se describen de manera más completa en las páginas
info.
• En Red Hat Enterprise Linux, cualquier documentación menos convencional asociada con
un paquete específico se puede encontrar en /usr/share/doc.
• El Proyecto de documentación de Linux brinda una gran cantidad de documentación
relacionada con Linux.
• Los manuales de Red Hat proporcionan documentación específica a la distribución de Red
Hat Enterprise Linux.
Discussion
Getting Help
Al avanzar el curso probablemente se dará cuenta de que a menudo Unix toma decisiones de
diseño en favor de la brevedad y la eficiencia más que de la transparencia al nombrar los
comandos y las opciones. Esto es en particular cierto para los comandos más utilizados tales como
mv, ps y vi. Esto hace de Unix una opción muy efectiva para el usuario conocedor, pero con
frecuencia a expensas del aprendiz.
Nadie recuerda todas las funcionalidades de cada uno de los comandos, pero los usuarios
experimentados de Unix saben cómo encontrar la información en línea de manera rápida. La
primera capa de ayuda con frecuencia la proporcionan los comandos mismos, en la forma de
"usages" o breves resúmenes de sintaxis que se producen cuando se invoca el comando con las
opciones -h, -? o --help. Los usos se abordaron en la lección anterior pero se mencionan otra vez
aquí para que todo esté completo.
30
Las páginas man
Las páginas del manual, con frecuencia abreviado como "páginas man", son la fuente tradicional
de referencia e información de los sistemas Unix. Puede ver las páginas de documentación para la
mayoría de los comandos, los formatos de archivos, las llamadas de programación y temas en
general, utilizando el comando man. Por ejemplo, man ls genera la documentación para el
comando ls.
El paginador less
Red Hat Enterprise Linux usa less para ver las páginas del manual. Al ver archivos (incluyendo las
páginas man) en less, se puede navegar utilizando solo letras: space se utiliza para ver la
siguiente página, b se utiliza para ver la página anterior, q es para salir. less se abordará en más
detalle en una lección posterior; sin embargo, la siguiente tabla resume algunos de los comandos
de navegación más útiles al ver las páginas man con less.
Comando Acción
space Ver la próxima página
b Ver la página anterior
q Salir
/ text Busca la palabra text
RETURN
n Encuentra la siguiente ocurrencia de la palabra que se buscó anteriormente
Capítulos Man
Las páginas man están organizadas en ocho capítulos estándares como se muestra en las
siguientes tablas. Algunas de las páginas comparten nombres idénticos en diferentes capítulos. Por
ejemplo, existen páginas tanto para el comando passwd, que se encuentra en el capítulo uno
sobre los comandos del usuario, como para el archivo /etc/passwd, que se encuentra en el capítulo
cinco que cubre los formatos de archivos. Infortunadamente, para el usuario que está tratando de
encontrar documentación sobre el formato del archivo /etc/passwd, man passwd sólo presenta la
primera página que encuentra, en este caso la entrada del capítulo uno. Para poder ver la página
man del capítulo cinco, se debe especificar explícitamente el capítulo como en man 5 passwd.
31
En Unix, las referencias a las páginas man usualmente incluyen el número del capítulo en
paréntesis despúes del número de la página, tal como passwd(1) o passwd(5). Cada capítulo tiene
una página de introducción llamada intro para que el comando man 5 intro presenta una
introducción al capítulo 5.
Dos de las opciones más utilizadas con el comando man son -k, para realizar búsquedas de
palabras y -a, para ver todas las "páginas relevantes" para un argumento. La usuaria madonna
está tratando de hallar información sobre el formato para el archivo /etc/passwd. Ya descubrió que
man passwd sólo presenta la página man para el comando passwd, así que utiliza man -k para
realizar la búsqueda de la palabra clave en passwd.
madonna obtuvo mucho más de lo que estaba buscando, pero incluida en la salida se
encuentra la referencia al archivo de la contraseña,y el hecho de que la información se
encuentra en el capítulo 5 de las páginas man.
Ahora madonna sabe cuál es el capítulo que necesita así que saca la página con man 5 passwd.
Otra opción podriá haber sido utilizar la opción -a, la cual hace que manvea todas las páginas
relevantes en orden.
Las páginas man usualmente están diseñadas para proporcionar información de referencia no
tutoriales o ayuda en un contexto en general. Los comandos mucho más complicados se
encuentran documentados en las páginas "info" con hipervínculos. Las páginas info preceden los
días de los navegadores y los enlaces. Dichas páginas se pueden ver ya sea utilizando el comando
info tradicional o Red Hat Enterprise Linux proporciona un comando similar con una interfaz más
fácil llamada pinfo. Las páginas info se utilizan principalmente para software desarrollador por the
GNU project.
32
El comando pinfo, sin argumentos, realizará una lista de la tabla de contenidos para todas las
páginas info instaladas. La navegación básica es similar al paginador less. Los enlaces entre las
páginas info se pueden cruzar utilizando las cuatro flechas como se señala en la siguiente tabla.
Comando Acción
SPACE Página siguiente
b Página anterior
q Salir
/text RETURN Busca la palabra text
FLECHA DERECHA Seguir el vínculo
FLECHA IZQUIERDA Atrás
FLECHA ARRIBA Enlace anterior
FLECHA ABAJO Siguiente enlace
El directorio /usr/share/doc
Uno de los principios de diseño detrás del software de código abierto con frecuencia se resume en
la frase "lanzamiento temprano, lanzamiento frecuente". Al desarrollar software, este se distribuye
tan pronto como sea útil así no se haya pulido o esté bien documentado todavía. El permitir a los
usuarios utilizar pronto el software, brinda la ventaja de que ellos pueden ayudar a influir en su
diseño continuo.
Red Hat Enteprise Linux adopta esta filosofía e incluirá software estable y útil aún si éste no se
encuentra formalmente documentado en las páginas man o en la páginas info. Con frecuencia, la
documentación sobre cómo utilizar los productos recién desarrollados puede ser un simple archivo
de texto llamado README, agrupados de manera rápida por el desarrollador. Red Hat Enteprise
Linux incluye tal documentación poco estructurada, pero útil dentro del directorio /usr/share/doc,
organizado por el paquete de Red Hat propietario del software.
Su dimensión variará de acuerdo con el grado de utilidad que tenga la documentación para un
paquete dado. Por ejemplo, elvis descubrió que la documentación informal proporcionada por el
visor de archivos PostScript ggv es muy poca, ya que consta del ChangeLog poco estructurado de
los desarrolladores. Con un poco de suerte, la falta de NEWS es una buena noticia.
En contraste, se puede encontrar mucha información sobre la configuración del complicado servicio
para compartir archivos, samba, bajo su directorio /usr/share/doc incluyendo los subdirectorios que
contienen documentación en una variedad de formatos.
33
Red Hat Enterprise Linux incluye manuales de documentación desarrollados como parte de un
servicio que Red Hat, Inc presta. Los siguientes manuales de documentación se encuentran
disponibles en online, en el CD de documentación en formato RPM o en los libros que vienen como
parte del paquete.
Estos manuales dan información específica sobre el sistema operativo de Red Hat Enterprise
Linux, incluyendo información básica e instrucciones paso a paso para varias tareas.
Las FAQs son una compilación de las Preguntas más frecuentes sobre un tema en
particular tal como FAQ sobre Linux-RAID.
HOWTOs
HOWTOs brinda instrucciones paso a paso sobre cómo configurar una faceta en particular
de Linux tal como el CD-Writing-HOWTO (como-grabar-CDs) o el ETHERNET-HOWTO
(como-eternet).
MANUALES
Los manuales proporcionan un cubrimiento más profundo sobre temas más amplios tales
como la administración de sistemas o incluso la programación del módulo del kernel de
Linux.
Aunque la documentación no es específica para la distribución Red Hat Enterprise Linux, gran
parte de la información es útil y relevante.
Por último, presentamos yelp, el navegador de ayuda de Gnome, el cual se puede reiniciar
seleccionando "Ayuda" del menú de aplicaciones. yelp proporciona la documentación básica para
muchas de las aplicaciones gráficas especificas de GNOME, incluyendo Nautilus File Manager y
los applets de GNOME.
34
Propiedades de Archivos regulares y Permisos
Conceptos clave
• Los archivos tienen usuario propietario, un grupo propietario, y una serie de permisos.
• Tres tipos de permisos: lectura (r), escritura (w) y ejecución (x)
• Tres clases de acceso: (u)suario, (g)rupo propietario, y (o)tro
• Ver la propiedad y los permisos de archivo: ls -l
• Modificar la propiedad y permisos:chmod, chgrp, y chown
Discusión
Linux es un entorno multiusuario y como tal, personas muy diferentes pueden estar trabajando al
mismo tiempo con una serie de archivos sencillos. Se espera que algunos de estos archivos sean
compartidos, de tal manera que muchas personas puedan verlos y modificarlos. Por ejemplo,
alguien puede estar haciendo la lista de regalos para un cumpleaños próximo. Entre más gente
pueda leer este archivo, mejor. Sin embargo, puede que haya otros archivos que se quieran
mantener en privado. Por ejemplo, muy poca gente querrá que alguien le lea su diario, otros
querrán tener un archivo de lectura para todos en el sistema, y permitirle a unos pocos modificarlo.
Cada archivo en Linux tiene tres propiedades que permiten a los usuarios controlar quién tiene
acceso al archivo y cómo: un usuario propietario, un grupo propietario y una serie de permisos
otorgados. Cuando un usuario crea un archivo, éste se convierte en el propietario del archivo del
usuario y por lo general, el grupo primario del usuario, se convierte en el propietario del archivo de
grupo. Un usuario no puede cambiar el archivo del usuario propietario, pero el usuario tiene
algunas habilidades para cambiar el grupo propietario. Los bits de permisos definen la forma como
las tres clases diferentes de usuarios pueden usar el archivo: el propietario del archivo, los
miembros del grupo que poseen el archivo y cualquier otro usuario.
La última columna es el nombre del archivo, mientras que la tercera y cuarta columnas, indican los
propietarios del archivo de usuario y grupo, respectivamente. En las siguientes secciones veremos
cómo utilizar la primera columna para determinar los permisos del archivo.
35
Al decidir quién puede tener acceso al archivo, un usuario puede distinguir entre tres tipos de
permisos. Alguien puede ver un archivo si tiene permisos de lectura, pero deberá tener permisos
de escritura para modificarlo. Los permisos de ejecución, permiten que alguien utilice el archivo
como un comando. Para iniciar una aplicación o ejecutar un script, el archivo que contenga la
aplicación o el script deberá ser ejecutable. Los archivos normales de datos no usan el tipo de
permiso ejecutable.
Cada archivo tiene una serie de permisos de lectura(r), escritura(w), y ejecución(X) para las tres
clases diferentes de acceso de archivo. El propietario del archivo utiliza el primer grupo. Los
miembros del grupo propietario del archivo utilizan el segundo y todos los demás que no estén
incluidos en las dos categorías anteriores utilizan el último. Los permisos de un archivo se
presentan, por lo general, con una serie de nueve caracteres, tales como rwxr-xr-x. Las primeras
tres letras representan los permisos del "usuario", las siguientes tres, los permisos del "grupo", y
las últimas tres el permiso del "otro". Una letra indica que el permiso correspondiente se ha
activado, mientras que si aparece un guión esto significa que no se tiene permiso.
Cuando alguien trata de acceder a un archivo, Linux hace las siguientes preguntas en este orden:
1. ¿El usuario es propietario del archivo? Si lo es entoces utiliza los permisos de usuario.
2. ¿El usuario es miembro del grupo que dueño del archivo? Si lo es entonces se utilizan los
permisos de grupo.
3. De lo contrario, se utilizan los otros permisos.
Ejemplos
[elvis@station elvis]$ echo "Había una vez un hombre peruano" > /tmp/limerick
[elvis@station elvis]$ ls -l /tmp/limerick
-rw-rw-r-- 1 elvis elvis 32 Jan 14 13:42 /tmp/limerick
Observe que por defecto, elvis posee el archivo y como propietario de archivo tiene permisos de
escritura y de lectura. Los otros usuarios sólo pueden leer el archivo (debido a que Red Hat
Enterprise Linux utiliza el esquema del grupo privado de usuario, el usuario elvis es también el
36
único miembro del grupo elvis). Como elvis tiene permisos para escribir, puede modificar el archivo
añadiendo la próxima línea del verso:
Otros usuarios como blondie, sin embargo, solo pueden leer el archivo. Cuando blondie trata de
sobrescribir el archivo con su propio verso, se da cuenta que no tiene los permisos apropiados.
user grupos
blondie blondie,music
elvis elvis,music,wrestle,physics,emperors
hogan hogan,wrestle
bob bob
Elvis es el propietario del archivo gigs, pero cualquiera que pertenezca al grupo music puede
leer o escribir en este archivo. Cualquier músico, puede añadir (o borrar) un evento en la
programación y cualquiera puede leer el archivo para saber cuándo tocan los músicos.
En contraste, blondie ha estado trabajando en el archivolyrics, el cual no está aún listo para
compartir. Aunque el archivo tiene permiso de escritura, es de propiedad del grupo de
blondie. Como Red Hat implementa el esquema de grupo privado de l usuario, la usuaria
blondie debería ser la única miembro del grupo blondie. Los permisos en lyrics tienen el
mismo efecto de aquellos en lyrics.old.
Hulk Hogan ha estado trabajando en routines para una función de lucha libre. Para no tomar
a otros luchadores (wrestlers en inglés) por sorpresa, ha dejado un archivo de sólo lectura
para todos los miembros del grupo wrestle. Observe que otros luchadores pueden leer el
37
archivo, pero no pueden cambiar ninguna de las rutinas. El que no sea miembro del grupo de
wrestlers no tiene acceso al archivo.
Archivos ejecutables
Los archivos que se deben interpretar como comandos necesitan tener permisos de ejecución.
El comando ls es ejecutable por cualquiera. Observe que el permiso de lectura no se necesita para
ejecutar el comando, pero permite a los usuarios ver el contenido del archivo (a menudo binario).
Los permisos de lectura para mozilla, por ejemplo, permiten a los usuarios observadores darse
cuenta de que el comando es realmente un script de texto navegable.
Enlaces simbólicos
A pesar de que los enlaces simbólicos tienen permisos, los permisos son siempre rwxrwxrwx. Las
decisiones de acceso "fracasan" de a cuerdo al archivo al que se refiere el enlace simbólico.
El comando view, el cual es en realidad un enlace simbólico, tendría los mismos permisos que:
rwxr-xr-x.
Ejercicios en línea
1. Haga una lista corta de propósitos para el año entrante en su editor de texto preferido o
simplemente desde la línea de comandos. Almacene el archivo en su directorio recién
creado como /tmp/nombredeusuario/resolutions.txt.
38
2. Conviértase en uno de sus usuarios de cuenta alterna. Puede reiniciar desde otra consola
virtual, desde una conexión de red o sencillamente con ejecutar su - al usuario alterno.
3. Como el usuario alterno, confirme si puede ver el archivo. Trate de añadir un nuevo punto
a la lista. ¿Por qué no puede modificar el archivo como el usuario alterno?
content_view let_
Deliverables A title Question 1
39
Cambio de permisos de archivos: chmod
Conceptos clave
Discussion
En la lección anterior, aprendimos que los archivos tienen permisos de lectura (r), escritura(w) y
ejecución(x); y tres clases de acceso ((u)suario, (g)rupo, y (o)tro, los cuales definen la manera en
que se puede utilizar el archivo. Los permisos son administrados por el comando chmod.
Usualmente, en Linux, al permiso de archivo se le conoce como el "modo" del archivo. El nombre
chmod es un atajo para cambiarmodo.
Por ejemplo, cuando alguien crea un archivo, por defecto el archivo puede ser modificado por sólo
una persona, pero puede ser leíble por todos en el sistema. Supongamos que elvis estuviera
trabajando en la letra de una nueva canción y no quisiera que nadie la leyera antes de haberla
terminado. Primero crearía el archivo y para no permitir a otros la lectura de éste, necesitaría
utilizar el comando chmod.
[elvis@station elvis]$ echo "Well, it's one for the honey," > blue_suede
[elvis@station elvis]$ echo "Two for the snow," >> blue_suede
[elvis@station elvis]$ ls -l blue_suede
-rw-rw-r-- 1 elvis elvis 48 Jan 16 08:09 blue_suede
[elvis@station elvis]$ chmod o-r blue_suede
[elvis@station elvis]$ ls -l blue_suede
Observe que en el primer uso del comando ls -l, el archivo tenía permiso de lectura para todos. Sin
embargo, después del comando chmod, el comando ls -l muestra que otros ya no lo pueden leer.
Cuando elvis haya decidido la letra de la canción entonces puede restaurar la lectura del archivo
para otros, utilizando una vez más chmod.
[elvis@station elvis]$ echo "Well, it's one for the money," > blue_suede
[elvis@station elvis]$ echo "Two for the show," >> blue_suede
[elvis@station elvis]$ echo "Three to get ready," >> blue_suede
[elvis@station elvis]$ echo "Now go, cat, go." >> blue_suede
[elvis@station elvis]$ ls -l blue_suede
-rw-rw---- 1 elvis elvis 48 Jan 16 08:10 blue_suede
[elvis@station elvis]$ chmod o+r blue_suede
[elvis@station elvis]$ ls -l blue_suede
-rw-rw-r-- 1 elvis elvis 85 Jan 16 08:11 blue_suede
El comando chmod le permite al usuario cambiar cualquier permiso asociado con un archivo. El
primer argumento está compuesto por una secuencia de letras que especifican las clases de
acceso, seguidas por los signos: más, menos, o igual y por otra secuencia de letras que
40
especifican el tipo de permiso a cambiar. Cualquier argumento subsecuente especifica una lista de
archivos para aplicar los cambios. La sintaxis se resume en la siguiente tabla:
abreviación interpretación
u user
g grupo
o otro
a todos
+ agregar
- borrar
= set
r leer
w escribir
x ejecutar
Ejemplos
La siguiente tabla presenta varios ejemplos de cómo el comando chmod se puede utilizar para
modificar permisos de un archivo llamadofoo, con los permisos predeterminados de rw-rw-r--. La
primera columna es un ejemplo del uso del comando chmod y la última columna son los permisos
que el archivo tendría después de ejecutar el comando.
41
chmod go=rx establece el permiso de lectura y ejecución pero no de rw-r-xr-x
foo escritura para el grupo y otro
A pesar de que las dos últimas entradas funcionarían, ¿por qué es difícil imaginar un uso para un
archivo con cualquiera de los dos permisos resultantes?
Ejercicios en línea
Lab Exercise
Objetivo: Cambiar permisos en un archivo de tal manera que otros no puedan leerlo.
3. Observe que los permisos en un archivo creado recientemente, le permiten a todos los
usuarios en el sistema leer el archivo. Asuma que quiere mantener sus propósitos en
secreto. Modifique los permisos de archivos de tal forma que los otros no tengan acceso de
lectura.
4. Al utilizar una de las cuentas alternas, confirme que otros usuarios en el sistema no
pueden leer sus propósitos.
Deliverables
42
A title
Question 1
content_view let_
43
Cambio de Propiedad de Archivos con el comandochgrp y chown
Conceptos clave
Discussion
En la lección anterior, aprendimos cómo modificar los permisos de un archivo y vimos un ejemplo
de cómo crear un archivo privado: el propietario del archivo podría leer el archivo, pero nadie más
lo puede hacer. ¿Qué sucedería si usted quisiera compartir el archivo con un grupo de personas
pero no con todos? o ¿qué pasaría si quisiera modificarlo? En estas situaciones, usted hace uso
del grupo propietario de archivo y de los permisos de grupo.
En el cuaderno anterior, vimos cómo los usuarios de Linux pertenecen a una colección de grupos.
Para repasar, cada usuario pertenece a un grupo primario y también a un número de grupos
secundarios. Cuando se crea un archivo nuevo, el propietario del archivo del grupo es establecido
como el grupo primario del creador. En Red Hat Enterprise Linux, éste sería usualmente el grupo
privado del creador. Debido a que usted es el único miembro, su grupo privado no es útil para
trabajar en colaboración. Para compartir el archivo, debe cambiar el propietario del archivo de
grupo. Esto se realiza con el comando llamadochgrp.
El primer argumento especifica el nuevo grupo propietario de archivo, mientras que los argumentos
subsecuentes listan los archivos cuyo propietario de grupo se va a cambiar. El propietario del grupo
sólo lo puede cambiar el usuario dueño del archivo, y el usuario debe ser un miembro del nuevo
grupo de propietarios del archivo.
En el siguiente ejemplo, el usuario ventura es un miembro del grupo wrestler y del grupo governor
(aparte de su grupo privado, ventura). Primero, desea crear un plan de impuestos que otros
gobernadores deberían poder leer pero no modificar y al cual nadie más debería tener acceso.
Para este fin, debe realizar los siguientes pasos:
1. Crear el archivo.
2. Cambiar el propietario del archivo de grupo al grupo governor utilizando el comando chgrp.
3. Cambiar permisos en el archivo desde los permisos predeterminados rw-rw-r-- a rw-r-----
utilizando el comando chmod.
[ventura@station ventura]$ id
uid=2306(ventura) gid=2308(ventura)
groups=2308(ventura),302(wrestle),305(governor)
44
-rw-rw-r-- 1 ventura ventura 21 Jan 16 09:55 taxplan.txt
En raras ocasiones, es necesario que el administrador cambie el usuario propietario del archivo.
Esto se puede hacer utilizando chown, cuya sintaxis es casi idéntica al del comando chgrp:
El primer argumento es el nombre del nuevo usuario del archivo y los argumentos siguientes son
los nombres de los archivos a cambiar. Sólo el usuario administrativo, root, puede usar chown, si
algún usuario pudiera cambiar el archivo del propietario, los permisos de acceso no tendrían
sentido.
Como root es el único que puede ejecutar el comando chown éste no se estudiará a fondo.
En general, sólo el propietario de un archivo puede cambiar los permisos o propiedades de archivo
de un archivo. Además, cuando se utiliza el comando chgrp, el archivo del nuevo propietario del
grupo, debe ser uno de los grupos subscritos del usuario. El usuario administrativo, root, puede
realizar cualquiera de estas operaciones. La tabla de abajo resume estas habilidades.
Ejemplos
Considere que al usuario ventura, quien es miembro de los grupos secundarios governor y wrestler
(aparte de su grupo privado, ventura) le gustaría compartir sus planes de lucha libre (wrestling) con
el usuario hogan y con otros miembros del grupo wrestle. Sin embargo, para impedir el acceso a
los que no son miembros del grupo wrestler, él ejecuta la siguiente secuencia de comandos.
45
[ventura@station ventura]$ chmod o-rw /tmp/plans.txt
[ventura@station ventura]$ chgrp wrestle /tmp/plans.txt
[ventura@station ventura]$ ls -l /tmp/plans.txt
-rw-rw---- 1 ventura wrestle 23 Jan 20 07:16 /tmp/plans.txt
¿Pudo el usuario ventura haber usado el comando chmod o-r /tmp/plans.txt para lograr el mismo
efecto en la secuencia anterior?
Ahora al usuario hogan le gustaría agregarse a los planes de ventura. Como miembro del grupo
wrestle tiene permiso para hacerlo.
Orgulloso de su contribución, a hogan le gustaría poner los planes a la vista de todos. Para ésto
hace el archivo disponible para sólo lectura para todod el mundo.
Aunque hogan es miembro del grupo wrestle, él no es el dueño del archivo. ¿Quiénes son los
únicos dos usuarios en el sistema que pueden cambiar el propietario del grupo del archivo?
Ejercicios en línea
Compartir un archivo con un grupo Lab Exercise Objetivo: Crear un archivo compartido entre
miembros de un grupo determinado. Tiempo estimado:15 minutos
Especificaciones
3. Recuerde que su primera cuenta alterna es también miembro del grupo wrestle.
Conviértase en su primer usuario alterno (i.e. estudiante_a). Usted puede reiniciar la sesión
46
desde la consola virtual, desde la conexión de red, o simplemente con el comando su - al
usuario alterno.
4. Como el usuario alterno, confirme que puede ver el archivo. También, observe que puede
modificar el archivo agregando un artículo más a la lista de mercado.
5. Recuerde que su segunda cuenta alterna (i.e, estudiante_b) no es un miembro del grupo
wrestle. Trate de convertirse en segundo usuario alterno y repita los pasos anteriores.
Usted podrá ver el archivo pero no modificarlo.
47
Propiedad de Directorios y Permisos
Conceptos clave
• Como los directorios también son archivos, tienen un usuario propietario de archivo, un
propietario de grupo y una serie de permisos.
• Los permisos de lectura permiten al usuario listar el contenido de un directorio.
• Los permisos de escritura le dan al usuario el derecho de agregar y borrar archivos.
• Los permisos de ejecución le dan derecho al usuario de acceder a un archivo dentro del
directorio.
• Los permisos de directorio se pueden modificar con el comando chmod.
Discussion
Permisos de Directorio
Cuando alguien está usando un archivo dentro de Linux, generalmente puede estar leyendo su
información, modificándola o tratando de ejecutar el archivo como un script o aplicación. Por lo
tanto, los tipos de permiso que ya hemos visto, a saber: lectura (r), escritura (w) y ejecución (x),
tienen muchas interpretaciones.
Para Linux, un directorio es solo un tipo especial de archivo, por lo tanto, tambien tiene las mismas
clases de permisos lectura (r), escritura (w) y ejecución (x), un usuario propietario, un grupo
propietario y las mismas clases de acceso ((u)suario, (g)rupo,y (o)tro). Sin embargo, es obvio que
los directorios se utilizan de una manera diferente. ¿Tendría sentido si abriéramos un directorio en
un editor tal como nano /home/elvis? Debido a que la gente usa directorios diferentes, los
permisos de directorio tienen diferentes interpretaciones.
¿Qué hace la gente con los directorios? Hacen la lista del contenido con el comando ls. Borran
archivos desde ahí, crean nuevos archivos dentro de ellos, y mueven archivos de un directorio a
otro. Los permisos de directorio deberían dar derecho al propietario del directorio de controlar quién
puede realizar estas operaciones.
Linux considera que hacer la lista del contenido de un directorio, (como con el comandols) es
análogo a "leer" un directorio, y por lo tanto, una persona debe tener permisos de lectura (r) para
listar su contenido. Agregar o suprimir un archivo desde un directorio se considera "escribir"el
directorio y por lo tanto alguien debe tener permisos de escritura (w) para barajar los archivos
dentro del directorio.
No hay una analogía razonable para "ejecutar" un directorio, por eso Linux no trata de definir una
conducta similar. En cambio, el permiso de ejecución (x) controla la conducta de los directorios, lo
que no tiene nada que ver con el comando de ejecución. Este permiso se conoce como el permiso
"buscar", pero como el tercer permiso ya ha sido llamado de "ejecución", para los archivos
regulares, se utiliza la misma palabra (y letra) para los directorios. Con el fin de referirse a cualquier
archivo dentro de un directorio, (incluyendo subdirectorios), un usuario debe tener permisos de
ejecución (x).
La primera fila de la siguiente tabla parece familiar. Esta repite cómo interpretar los permisos para
archivos regulares. Se ha agregado una fila para directorios para comparar y contrastar la
interpretación del permiso de ambos tipos de archivo.
48
Table 1. Permisos para archivos regulares y directorios
Ejemplos
Los archivos normales recién creados son de lectura para todos, pero sólo el usuario y el grupo
propietario del archivo pueden modificarlos. ¿Cómo se manejan los directorios recién creados?
Estudie el caso de nero, quien está recolectando información del censo de varias provincias. El
decide crear un directorio llamado /tmp/censuspara guardar todos los datos.
Observe que los permisos predeterminados para los directorios recién creados son rwxrwxr-x.
Estos permisos tienen las siguientes implicaciones:
Por ejemplo, julius decide que le gustaría hojear la información que tiene nero sobre el censo.
Observe que julius puede navegar los directorios y los archivos dentro de los directorios, pero
debido a los permisos por defecto de un directorio, él no puede agregar ni suprimir nuevos
archivos. A causa de los permisos predeterminados de archivo, él puede ver, pero no modificar el
contenido de los archivos.
49
[julius@station julius]$ echo "110 CE 42" > /tmp/census/thrace.dat
-bash: /tmp/census/thrace.dat: No such file or directory
Directorios de inicio
En Red Hat Enterprise Linux, un directorio de inicio no sigue los permisos predeterminados.
En Red Hat Enterprise Linux, los directorios de inicio están "protegidos". Por defecto, sólo el
usuario propietario de un directorio de inicio tiene permisos de buscar.
¿Ha notado que la mayoría de nuestros ejercicios que involucran a varios usuarios entrando a un
archivo han utilizado el directorio /tmp/nombredeusuario en lugar del directorio de inicio del
usuario? ¿Por qué razón no hemos utilizado el directorio de inicio del usuario?
Ahora a Nero le gustaría hacer pública su información sobre el censo. Usualmente, en Red Hat
Enterprise Linux, hay sólo dos lugares en donde los usuarios pueden crear archivos, el directorio
/tmp y ~ (el directorio de inicio del usuario). En el primer ejemplo, nero escoge crear un directorio
censusdentro de /tmp. Sin embargo, en Red HatEnterprise Linux, el directorio /tmp es "barrido.". Si
en 10 días no se ha tenido acceso a un archivo dentro de /tmp, éste se borra del sistema. Nero
necesita buscar un sitio mejor.
Con el fin de crear un sitio accesible al público permanente para sus datos del censo, nero escoge
crear un subdirectorio público dentro de su directorio de inicio. Convencionalmente, un
subdirectorio como tal en Linux, se llama pub. Como las siguientes secuencias lo mostrarán,
compartir archivos desde el directorio de inicio del usuario, no es tan fácil como crear un directorio
leible (r) o ejecutable (x) por todo el mundo.
Primero, nero crea el directorio ~/puby copia en él la información del censo desde /tmp/census.
50
[nero@station nero]$ ls -al /home/nero/pub/
total 20
drwxrwxr-x 2 nero nero 4096 Jan 16 16:13 .
drwx------ 4 nero nero 4096 Jan 16 16:12 ..
-rw-rw-r-- 1 nero nero 42 Jan 16 16:13 egypt.dat
-rw-rw-r-- 1 nero nero 42 Jan 16 16:13 gaul.dat
-rw-rw-r-- 1 nero nero 42 Jan 16 16:13 iberia.dat
Recuerde que "."siempre se refiere al directorio actual en este caso/home/nero/pub.
Recuerde que ".." siempre se refiere al directorio padre actual en este caso /home/nero.
Nero revisa concienzudamente los permisos en el directorio y los archivos recién creados. En
/home/nero/pub encuentra los permisos de rwxrwxr-x, lo que implica que otros pueden buscar una
lista de archivos desde el directorio. Los archivos mismos de datos tienen permisos de rw-rw-r--, es
decir que otros tienen acceso a los archivos. Como todo parece estar en orden, le dice a julius
dónde encontrar la información.
Interesado en los datos, julius trata de tener acceso a los archivos. Infortunadamente, no todo sale
bien:
¿Qué ha olvidado nero? Recuerde que para tener acceso al archivo dentro de un directorio,
incluyendo los subdirectorios, un usuario debe haber buscado permisos para el directorio. Los
permisos en /home/nero/pub están correctos, pero observe los permisos en /home/nero (".." en la
lista de arriba o listados de nuevo a continuación):
Si julius pudiera tener acceso al archivo /home/nero/pub, todo estaría bien. Pero como julius no
tiene los permisos de búsqueda para /home/nero, no puede tener acceso a /home/nero/pub. Para
crear un directorio accesible al público dentro de un directorio de inicio, el usuario debe permitir a la
gente buscar en su directorio de inicio. Nero arregla el problema en la siguiente secuencia de
comandos.
julius trata de nuevo de examinar el archivo. Como los permisos en /home/nero/pub le dan acceso
de lectura(r) y ejecución (x) a otros, julius busca archivos y obtiene un listado de directorio.
51
110 CE 45430
120 CE 53200
130 CE 55820
[julius@station julius]$ ls /home/nero/pub
egypt.dat gaul.dat iberia.dat
Es frecuente que los usuarios permitan a otros usuarios el acceso a sus directorios de inicio
(considere, el ejemplo anterior). Al permitir a otros ejecutar (x), pero no lee(r) en su directorio de
inicio, otros usuarios deben saber que un directorio existe dentro del directorio de inicio para tener
acceso a éste. Debido a que otros usuarios no pueden usar el comando ls para descubrir el
contenido de su directorio de inicio, los directorios de inicio de los usuarios permanecen siendo
privados y sólo las partes que ellos quieran exponer estarán disponibles a otros usuarios.
Aunque el no añadir permisos de lectura (r) al directorio de inicio brinda alguna protección contra
otros usuarios que estén navegando, ésta no es infalible. Otros usuarios pueden aún "adivinar" el
contenido de un directorio del cuál tienen permisos para ejecutar (x) pero no de lectura (r). Por
ejemplo, los usuarios usualmente crean un directorio llamado ~/mail, para almacenar mensajes.
Suponga que nero le ha dado a otros permiso de ejecución (x) a su directorio de inicio (como en el
ejemplo anterior), y más tarde crea un directorio ~/mail. Si elvis fuera a adivinar si dicho directorio
existe, los permisos por defecto en ~nero/maille permitirían navegar sus contenidos. Esto se
muestra en la siguiente transcripción:
52
[elvis@station elvis]$ cat ~nero/mail/sent
2002
Ejercicios en línea
Creación de directorios públicos para grupos distintos Lab Exercise Objetivo: Crear directorios
accesibles a grupos dentro del directorio de inicio de un usuario
Especificaciones
Su cuenta debería ser miembro de dos grupos secundarios, music y wrestle. aparte de su grupo
privado. Además, su primera cuenta alterna debe ser un miembro de los grupos wrestle y physics,
mientras que su tercera cuenta alterna debería ser un miembro del grupo music.
Desde dentro de su directorio de inicio, usted quisiera compartir información con otros músicos y
luchadores, pero no le gustaría que los músicos vieran la información de los luchadores y vice
versa. Usted preferiría que un grupo ni siquiera se diera cuenta de la existencia de otro directorio
de grupo. Adopte el siguiente plan:
53
4. Cree los archivos ~/pub/music/lyricsy ~/pub/wrestle/plan. Los miembros de los grupos
music y wrestle deberían poder leer y escribir respectivamente.
Cuando haya terminado, usted debería poder confirmar la conducta apropiada utilizando sus
cuentas alternas (student_a y student_c).
1. 1 Un directorio de inicio de búsqueda para todos y donde sólo usted puede listarlo.
2. ~/pub, un directorio de búsqueda para todos y de listado sólo para usted.
3. ~/pub/music, un directorio de búsqueda y que solo los miembros del grupo music pueden
listar.
4. ~/pub/music/lyrics, un archivo de lectura y escritura para todos los miembros del grupo
music.
5. ~/pub/wrestle, un directorio de búsqueda y que solo los miembros del grupo wrestle
pueden listar.
~/pub/wrestle/plan, un archivo de lectura y escritura para los miembros del grupo wrestle.
content_view let_
Ayudas
La siguiente serie de comandos demuestra una solución posible para hacer el directorio
~/pub/music.
54
[student@station student]$ mkdir ~/pub/music
[student@station student]$ chmod o-rx ~/pub/music/
[student@station student]$ chgrp music ~/pub/music
[student@station student]$ ls -al ~/p
total 16
Protección de subdirectorios dentro del directorio de inicio Lab Exercise Objetivo: Proteger un
subdirectorio recién creado dentro de su directorio de inicio, de una navegación no intencionada.
Estos ejercicios asumen que otros ya tienen permisos de ejecución (x) en su directorio de inicio.
Cree un subdirectorio memos en su directorio de inicio y modifique sus permisos de tal manera que
otros en el sistema no tengan acceso al directorio. Cree un archivo dentro del directorio y use una
de las cuentas alternas para confirmar que otros usuarios no puedan acceder al archivo.
Solución:La siguiente serie de comandos demostró una solución posible para las especificaciones
anteriores (la salida asume que usted acaba de completar el ejercicio anterior).
Conceptos clave
Discussion
55
En las lecciones anteriores, el comandochmod se utilizó para modificar permisos de un archivo
utilizando una sintaxis simbólica como la siguiente:
Esta sintaxis tiene algunas ventajas y desventajas. Como la sintaxis es muy legible, la intención de
un comando es bastante evidente: el estudiante no quiere que otros usuarios lean el archivo diary..
¿Cuáles son los permisos resultantes en diary? Un problema de sintaxis es que, al saber que sólo
este comando fue ejecutado, usted no puede decir si el archivo tiene permisos de escritura para los
miembros del grupo o para otros. Sin saber los permisos originales, usted no puede saber.
Esta lección ilustrará una sintaxis octal alterna para el comando chmod, la cual resuelve estos
problemas:
Después de aprender la sintaxis, usted sabría que, al ejecutar el comando anterior, el archivo diary
tendría permiso de rw-------. Como un beneficio agregado, una vez aprendida, la sintaxis octal
tiende a ser más rápida para el usuario.
Recuerde que un archivo tiene tres tipos diferentes de permisos (lectura (r), escritura (w) y
ejecución (x), para las tres clases de usuario: usuario propietario (u), grupo propietario (g), y otro
(o)). Con la notación octal, cada clase de acceso obtiene un dígito, las "centenas" para el usuario
(u); las "decenas" para el grupo (g) y las "unidades" para otro (o) . A cada tipo de permiso se le
concede un valor: (r) tiene 4, (w) tiene 2, y (x) tiene 1. Los dígitos de una notación octal son la
suma de los permisos concedidos para cada clase de acceso. Los siguientes ejemplos demuestran
cómo se traducen los números octales a una sintaxis convencional de permisos.
755 = rwxr-xr-x
640 = rw-r-----
701 = rwx-----x
Esta notación se llama la notación "octal" debido a que cada dígito tiene 8 posibles valores(de 0 a
7).
Modos de archivos
56
Una vez aprendida, la notación octal brinda una forma rápida de referirse a los permisos de
archivo. Por ejemplo, los administradores experimentados de Linux a menudo se referirán a un
permiso de archivo de "644" o de un directorio de "755". En Unix, al estado de los permisos de
archivo se les conoce como el modo de un archivo. En particular, este término se utiliza para
referirse a los permisos de archivo de notación octal. Por ejemplo, un administrador de sistema
podría decir que los "Directorios se crean con un modo predeterminado de 755".
Ejemplos
Al usuario elvis le gustaría establecer un directorio compartido ~/drafts. Quisiera que los miembros
del grupo music tuvieran libre acceso al directorio y que otros usuarios no. Al utilizar el comando
chmod, elvis utilizará la notación octal.
57
Mal uso de la notación octal
El usuario einstein tiene la siguiente serie de artículos, algunos ya han sido publicados, otros no.
Todos los archivos y direcciones tienen permisos predeterminados.
papers/
|-- published/
| `-- relativity
`-- unpublished/
|-- eismcsquared
|-- photoelectric_effect
`-- unlikely/
`-- time_travel
El usuario einstein ahora decide cambiar los permisos en todos sus archivos dentro de su directorio
sin publicar, para que otros usuarios no puedan leerlos. Con el fin de ahorrar tiempo, einstein
decide utilizar la forma recursiva del comando chmod.
¿Qué lección nos deja este ejemplo? Los directorios y archivos regulares tienen diferentes
permisos "razonables". Por ejemplo, los directorios deben tener establecido el permiso de ejecutar
(x), mientras que, por lo general, los archivos regulares no. Infortunadamente, el comando chmod -
R no distingue entre archivos y directorios.
(Con el fin de obtener el resultado deseado, einstein podría utlilizar el comando find para buscar de
modo recursivo. Dicho comando find se presentará en la siguiente sección).
Ejercicios en línea
58
Administración de Permisos en Grupos de Archivos Lab Exercise Objetivo: Administrar permisos
en un grupo grande de archivos, utilizando la notación octal.
Configuración
Su segunda cuenta alterna (student_b) debe ser miembro del grupo emperors. Inicie la sesión bajo
esa cuenta y cree un directorio ~/reports y ejecute el comando cd en ese directorio.
Use el siguiente comando "mágico" para crear un número grande de archivos en el directorio
actual. La sintaxis de paréntesis que está utilizando será presentada en un cuaderno posterior.
Especificaciones
Use el comando chmod con una notación octal para obtener estos resultados.
59
El directorio ~/reports y todos sus archivos y directorios subyacentes, deberían pertenecer al grupo
propietario emperor.
Possible Solution
The following sequence of commands provides one possible solution to this exercise.
60
Control de permisos por defecto: umask
Conceptos clave
• A nivel de Kernel, Linux crea archivos con el modo por defecto de 666 (rw-rw-rw).
• En el nivel de kernel de Linux cree directorios con el modo por defecto de 777(rwxrwxrwx).
• Cada proceso posee un parámetro "umask", el cual desenmascará alguno de estos
permisos por defecto.
• En Red Hat Enterprise Linux, el umask por defecto para usuarios estándar es 002.
• La umask de la shell bash se puede modificar con el comando umask.
Discussion
En las lecciones anteriores vimos que los archivos recién creados tienen un modo por defecto de
664 (rw-rw-r--), lo que implica que todos pueden leer el archivo, pero únicamente el propietario de
archivo puede modificar un archivo recién creado. Igualmente, los directorios recién creados tienen
un modo por defecto de 775 (rwxrwxr-x), implicando que cualquier persona puede acceder o
navegar en el directorio, pero sólo el propietario del directorio puede añadir o borrar archivos.
Los permisos predetermiandos de los archivos recién creados se pueden alterar a través de un
concepto Unix estándar llamado umask. Cada proceso, incluyendo el comando de shell bash, tiene
un número octal de tres dígitos, el cual se utiliza para "desenmascarar". La umask está compuesta
justo como un modo octal, pero el significado es invertido. Como un modo octal, cada clase de
acceso es representado por un sólo dígito: (u)suario está en las "centenas", (g)rupo propietario en
las "decenas" y (o)tros en las "unidades". Como un modo octal, cada tipo de permiso tiene un valor,
4 para lectura (r), 2 para escritura (w), y 1 para ejecución(x). Sin embargo, a diferencia de los
modos octales, la umask está compuesta por valores de permisos no deseados.
Con el fin de determinar los permisos para archivos recién creados, el kernel de Linux comienza
con un modo global por defecto de 666, (rw-rw-rw). El kernel luego aplica la umask para el proceso
que creó el archivo. Todos los valores asignados en la umask son "revelados" de los permisos
predeterminado de 666. Por ejemplo, una umask de 002 resultaría en permisos por defecto de 664:
Otro ejemplo, una umask de 077 resultaría en permisos por defecto de 600:
61
Al determinar los permisos por defecto, cualquier permiso que sea asignado en la umask es
"desenmascarado" del kernel predeterminado.
Los permisos predeterminados para los directorios se crean utilizando la misma técnica, excepto
que el modo por defecto del kernel para directorio es 777 (rwxrwxrwx). Por ejemplo, una umask de
002 resultaría en permisos por defecto para directorios de 775:
Observe que, en ambos casos, una umask de 002 tiene el mismo efecto general para los archivos
y directorios. Cualquiera puede leer, pero sólo el propietario puede modificar. Igualmente, una
umask de 077 tiene el mismo efecto general tanto en archivos como en directorios: el usuario
propietario puede leer y modificar, pero nadie más tiene acceso.
La umask de shell bash se puede examinar y modificar con el comando umask. Cuando se llama
sin argumentos, el comando umask reporta la umask de shell actual. Cuando se llama con una
umask octal como un único argumento, se le asigna a la umask de shell el valor especificado.
(Observe que, en la salida, la umask se reporta como un número octal de cuatro dígitos. Por ahora,
el "0" del comienzo se puede ignorar (su significado será más claro en la siguiente lección).
Ejemplos
Uso del comando umask para crear archivos compartidos por grupos
En la siguiente secuencia, blondie y otros músicos están colaborando con la letra de una canción.
A blondie le gustaría crear varios archivos que los miembros del grupo de music pueden ver y
modificar, pero que nadie más puede leer o escribir. Una posibilidad sería crear los archivos y
62
luego cambiar los permisos de archivo con chmod. En cambio, blondie va a utilizar el comando
umaskpara cambiar sus permisos por defecto de shell en los archivos recién creados.
Observe que la umask de shell de 007 "desenmascaró" los permisos que hubiesen podido ser
asignados por (o)tros.
El emperador Nero, en un estado de paranoia está sospechando que los otros usuarios le están
mirando sus archivos. Quisiera configurar su shell bash de tal forma que cada vez que inicie, la
umask de la shell sea establecida automáticamente como 077. Hará esto editando el archivo
~/.bashrc, el cual por lo general, existe por defecto en el directorio de inicio del usuario.
Siempre que se inicia una nueva shell bash, los comandos listados en el archivo especialmente
nombrado ~/.bashrc se ejecutan como si fueran escritos desde la línea de comandos. Al anexar
"umask 077" al archivo ~/.bashrc de nero, él configurará su shell de tal forma que la umask de shell
automáticamente será configurada como 077 al iniciar.
En la siguiente secuencia, nero examina primero, luego agrega una nueva línea y después
reexamina su archivo ~/.bashrc. Por ahora, no se preocupe por el contenido original del archivo,
sólo observe que el archivo modificado ejecuta el umask como su último comando.
63
[nero@station nero]$ cat ~/.bashrc
# .bashrc
Ejercicios en línea
Lab Exercise
Objetivo: Uso del archivo ~/.bashrc para cambiar los permisos por defecto de la shell bash.
Especificaciones
Cada vez que inicie una shell bash, el contenido del archivo ~/.bashrcse ejecutará como si los
hubiera escrito en la línea de comandos. Este archivo se utiliza a menudo para personalizar la
conducta predeterminada de bash.
64
Si quiere que su umask de shell por defecto sea cambiada automáticamente cada vez que inicia
una sesión, agregue una línea al final de su archivo ~/.bashrc, el cual establece la umask de la
shell. Los archivos recién creados deberían ser de lectura para todos, pero de escritura únicamente
para el usuario propietario por defecto.
Un archivo ~/.bashrc que establecezca la umask de shell bash por defecto de tal manera que los
archivos sean de lectura para todos pero sólo de escritura para el usuario propietario del archivo
(en particular, el archivo no debería ser de escritura para el grupo propietario).
Possible Solution
The following sequence of commands provides one possible solution to this exercise.
Observe que los permisos de los archivos recién creados es 644, no el permiso por defecto de Red
Hat de 664.
Limpieza
65
The Linux FileSystem
Detalles de archivo
Conceptos clave
Discussion
Suponga que elvis abre el editor de texto y hace la siguiente lista de mercado.
Eggs
bacon
milk
Cuando termina, y cierra el editor, le preguntan cómo le gustaría llamar al archivo. Escoge
shopping.txt. Luego, lista el contenido del directorio para asegurarse de que esté ahí.
[elvis@station elvis]$ ls -l
total 4
-rw-rw-r-- 1 elvis elvis 16 Jul 11 07:54 shopping.txt
Este corto ejemplo ilustra los tres componentes que Linux asocia con un archivo.
data
Los datos son el contenido del archivo, en este caso, los 16 bytes que componen la lista
del mercado de elvis (13 caracteres visibles y 3 invisibles de "retorno" que indican el final
de la línea). En Linux como en Unix, cada contenido de archivo se almacena como una
serie de bytes.
metadatos
66
propietario de archivo, el grupo propietario y los permisos. Información, tal como la última
vez que el archivo fue modificado o leído, también se almacena. Muchos de estos
metadatos son reportados al ejecutar el comando ls -l. En Linux (Unix), toda la información
adicional asociada al archivo (con la excepción importante que pronto veremos) se
almacena en una estructura llamada inodo.
filename
En resumen, hay tres estructuras asociadas con cada archivo: unadentry, la cual contiene un
nombre de archivo y se refiere a un inodo, el cual contiene los metadatos del archivo y se refiere a
datos del archivo. El entender las relaciones entre estas estructuras le ayudará a entender más
adelnate otros conceptos, tales como enlaces y directorios. Estas estructuras están resumidas así:
En Linux (y Unix), cada archivo existente en el sistema de archivos tiene un inodo asociado, el cual
almacena toda la información de los archivos, a excepción del nombre de archivo. ¿Qué puede
encontrar en un inodo?
Tipo de archivo
En Linux (y UNIX), el término archivo tiene un significado muy general: cualquier cosa que
exista en el sistema de archivos (y por tanto, tiene un inodo asociado con éste) es un
archivo. Esto incluye archivos regulares y directorios, que ya hemos visto, enlaces
simbólicos y nodos de dispositivos que veremos pronto, y un par de criaturas más oscuras
67
relacionadas con la comunicación entre procesos y que van más allá del alcance del curso.
Los posibles tipos de archivos se presentan en la siguiente tabla.
Cada uno de los siete tipos de archivos mencionados anteriormente utiliza la misma
estructura de inodo, por lo tanto, cada uno tiene los mismos tipos de atributos: propietarios,
permisos, modificar tiempos, etc. Cuando se listan los archivos con ls -l, el tipo de archivo
del archivo es identificado por el primer caracter, utilizando las abreviaturas de la segunda
columna.
Note
El término file está sobrecargado en Linux (Unix) y tiene dos significados. Cuando se utiliza
en oraciones tales como "cada archivo tiene un inodo", el término se refiere a cualquiera de
los tipos de archivo listados en el cuadro anterior. Cuando se utiliza en oraciones tales como
"El comando head sólo funciona en archivos, no en directorios", el término archivo se refiere
sólo al tipo específico de archivo que contiene datos. Por lo general, el significado es claro en
el contexto. Cuando tiene que hacerse alguna distinción, se utiliza el término archivo regular
como en "El comando ls -l identifica archivos regulares con un guión (-)".
Propiedades y Permisos
Al listar archivos con ls -l, la primera columna muestra los permisos (y el tipo de archivo),
la tercera, el usuario propietario y la cuarta, el grupo propietario.
Información de temporización
Cada inodo almacena tres tiempos importantes para el archivo: el atime , el ctime y el
mtime . Estos tiempos registran la última vez que se tuvo acceso (leído), cambiado, o
modificado, respectivamente.
68
ctime Cambia Tiempo Actualiza cada vez que la información del inodo de archivo
cambia
mtime Última Actualiza cada vez que cambian los datos del archivo
modificación
A menudo, la gente confunde el ctime con un "tiempo de creación". Aunque parezca raro, el
Unix tradicional ( y Linux) no registra el tiempo preciso en que el archivo se creó. Algunas
personas han identificado la falta de un tiempo de creación como una debilidad en el diseño
del sistema de archivos de Unix.
Longitud y tamaño del archivo
Conteo de enlaces
Por último, el inodo registra un conteo de enlaces entre archivos o el número de dentries
(nombres de archivos) que se refieran al archivo. Por lo general, los archivos regulares
sólo tienen un nombre y el conteo de enlace es uno. Sin embargo, esto no siempre es el
caso. Al listar los archivos con ls -l, la segunda columna entrega el conteo de enlaces.
Red Hat Enterprise Linux incluye el comando stat para examinar en detalle la información del inodo
de un archivo. En la programación de Unix, a una colección de archivos de información de inodo se
le denomina estatus del archivo. El comando stat reporta el estatus de un archivo.
Note
El comando stat generalmente no está instalado por defecto en Red Hat Enterprise Linux. Si
se encuentra con que su máquina no tiene el comando stat, haga que su instructor le instale
el archivo del paquete stat RPM.
69
Opción Efecto
-c, Sólo muestra la información solicitada usando el formato especificado. Para
--format=FORMAT mayor información, vea la página del manual stat (1).
-f, --filesystem Muestra la información sobre el sistema de archivos al que el archivo
pertenece, en lugar del archivo.
-t, --terse Muestra salida en formato terso (una línea)
El nombre del archivo. Esta es la información que no está realmente almacenada en el inodo,
sino en la dentry, como se explicó anteriormente.
De modo poco práctico para la terminología presentada anteriormente, el comando stat
etiqueta la longitud de un "tamaño" de un archivo.
El número de bloques del sistema de archivos que el archivo consume. Aparentemente, el
comando stat está usando un tamaño de bloque de 2 kilobytes. [1]
El tipo de archivo, en este caso, un archivo regular.
El conteo de enlaces o número de nombres de archivo que se enlazan a este inodo (no se
preocupe si no entiende esto aún).
El usuario propietario del archivo, el grupo propietario y los permisos.
Cuando el comando stat es conveniente para listar la información del inodo de archivos
individuales, el comando ls suele hacer un mejor trabajo resumiendo la información para varios
archivos. Volveremos a ver el comando ls, esta vez para discutir algunas de las opciones
importantes para mostrar la información del inodo.
ls [OPCIÓN...] ARCHIVO...
Opción Efecto
-a, --all Incluye archivos que empiezan con .
-d, --directorio Si ARCHIVO es un directorio, lista información acerca del directorio mismo y
no sobre el contenido del directorio.
70
-F, --clasificar Agrega al nombre de archivos alguno de estos *, /, =, @ ó | para indicar el
tipo de archivo.
-h, --leíble por Usa abreviaturas "leíbles por humanos"cuando reporta la longitud de
humanos archivos.
-i, --inodo Lista el número de índice de cada inodo de archivo.
-l Usa formato de listado largo
-n, --numeric-uid- Usa UIDs y GIDs numéricos en vez de nombres de usuario y nombres de
gid grupo.
-r, --reverse Invierte el orden de la clasificación.
-R, --recursivo Lista subdirectorios de modo recursivo.
--time=WORD Reporta (o clasifica) tiempo especificado por WORD en lugar de mtime.
WORD puede ser "atime", "access", "ctime" o "estatus".
-t Clasifica por tiempo de modificación.
En el siguiente ejemplo, madonna toma un listado largo de todos los archivos en el directorio
/usr/games. Los diferentes elementos que ls -l reporta se discuten en detalle.
El número total de bloques que los archivos utilizan en el directorio (observe que esto no
incluye subdirectorios).
El tipo de archivo y los permisos del archivo.
El conteo de enlaces del archivo o el número total de dentries (nombres de archivos) que se
refieren a este archivo (observe que, para los directorios, éste es siempre mayor que ¡1!
ummm...)
El propietario del archivo.
La longitud del archivo en bytes (observe que los directorios tienen una longitud también y que
la longitud parece aumentar en bloques, ummm....)
El mtime del archivo o la última vez que se modificó el archivo.
Mientras que la gente tiende a usar nombres de archivos para identificar archivos, el kernel de
Linux suele usar el inodo directamente. Dentro de un sistema de archivos, a cada inodo se le
asigna un número único de inodo. El número inodo de un archivo se puede listar con la opción -i
para el comando ls.
71
[elvis@station elvis]$ ls -s /bin
total 4860
4 arch 0 domainname 20 login 92 sed
96 ash 56 dumpkeys 72 ls 32 setfont
488 ash.static 12 echo 72 mail 20 setserial
12 aumix-minimal 44 ed 20 mkdir 0 sh
0 awk 4 egrep 20 mknod 16 sleep
...
En este ejemplo, el directorio chromium tiene un número inodo de 540838. Un archivo se puede
identificar de manera única si se conoce su sistema de archivos y el número de inodo.
Ejemplos
El usuario elvis está examinando los tamaños de los archivos ejecutables en el directorio /bin.
Primero ejecuta el comando ls -s.
Luego para cada nombre de archivo, el comando ls reporta el tamaño del archivo en kilobytes. Por
ejemplo, el archivo ash ocupará 96 Kbytes de espacio en el disco. En la salida (abreviada), que
todos los tamaños son divisibles por cuatro. Aparentemente, cuando se almacena un archivo en el
disco, el espacio de disco asigna espacio de disco a los archivos en fragmentos de 4 Kbytes, (esto
se denomina un "tamaño de bloque" del sistema de archivos). Tenga en cuenta que el archivo awk
parece no estar ocupando ningún espacio.
Esta vez, las longitudes de los archivos se reportan en bytes. Volviendo a mirar en el archivo ash,
la longitud es reportada como 92444 bytes. Esto es razonable porque redondeando a los próximos
4 Kilobytes, obtenemos los 96 Kbytes reportados por el comando ls -s. Observe otra vez el archivo
awk. El archivo no es un archivo regular, sino un enlace simbólico, lo que explica el porqué no
estaba consumiendo espacio. Los enlaces simbólicos se verán en más detalle próximamente.
Por último, elvis quiere saber acerca de los permisos en el directorio /bin. Sin embargo, cuando
ejecuta ls -l /bin, obtiene una lista de contenido del directorio /bin, no del directorio mismo.
Resuelve su problema agregando la opción -d.
72
[madonna@station madonna]$ ls -iF /usr/games/
540838 chromium/ 540564 fortune* 312180 Maelstrom/
El usuario prince está explorando los archivos de registro del sistema en el directorio /var/log. Le
interesa saber acerca de la actividad reciente en el sistema, por eso quiere saber cuáles archivos
han sido accedidos recientemente. Hace un listado largo del directorio y comienza a examinar las
últimas modificaciones reportadas de los archivos.
Con 74 archivos para examinar, prince rápidamente se cansa de revisar los archivos recientes.
Decide dejarle este trabajo dispendioso al comando ls, especificando que la salida se debería
ordenar por mtime con la opción -t.
Ahora elvis puede leer fácilmente los archivos cron, maillog y messages como los archivos
modificados más recientemente. Interesado en saber cuáles archivos de registro no se están
utilizando, prince repite el comando, agregándole la opción -r.
73
[prince@station prince]$ ls -ltr /var/log
total 16296
-rw-r--r-- 1 root root 32589 Oct 23 2001 xorg.1.log.old
drwxr-xr-x 2 servlet servlet 4096 Jan 20 2002 ccm-core-cms
drwxr-xr-x 2 root root 4096 Feb 3 2002 vbox
-rwx------ 1 postgres postgres 0 Apr 1 2002 pgsql
drwx------ 2 root root 4096 Apr 5 2002 samba
-rw-r--r-- 1 root root 42053 May 7 2002 xorg.1.log
-rw-r--r-- 1 root root 1371 May 9 2002 xorg.setup.log
-rw------- 1 root root 0 Jun 9 2002 vsftpd.log.4
...
Dado que ella no tiene una terminal en color, tiene dificultad para distinguir entre un archivo regular
y un directorio. Agrega la opción -F para representar la salida.
Ahora, los diversos archivos se representan por tipo. Los directorios terminan en un /, los enlaces
simbólicos en un @, y los archivos regulares con permisos ejecutables (lo que implica que son
comandos que se deben ejecutar) terminan en un *.
Ejercicios en línea
Ver los metadatos de un archivo Lab Exercise Objetivo: Listar archivos de acuerdo con la última
modificación Tiempo estimado: 5 minutos.
Especificaciones
74
1. Cree un archivo en su directorio de inicio llamado etc.bytime. El archivo debe contener un
listado largo del directorio /etc; ordenado de acuerdo con la última modificación. El archivo
modificado más reciéntemente debería estar en la primera línea del archivo.
2. Cree un archivo en su directorio de inicio llamado etc.bytime.reversed. El archivo debe
contener un listado largo del directorio /etc, ordenado a la inversa de acuerdo con la última
modificación. El archivo modificado más reciéntemente debería estar en la última línea de
la lista del archivo.
3. Cree un archivo llamado etc.inum que contenga el número de inodo del directorio /etc
como su único símbolo, (observe que está pidiendo el inodo del directorio mismo).
1. Un archivo llamado etc.bytime que contiene un listado largo de todos los archivos en el
directorio /etc, ordenado de acuerdo con la última modificación, con el primer archivo
modificado más recientemente en primer lugar.
2. Un archivo llamado etc.bytime.reversed que contiene un listado largo de todos los archivos
en el directorio /etc, ordenado de acuerdo con la última modificación, con el último archivo
más reciéntemente modificado, en primer lugar.
3. Un archivo llamado etc.inum que contiene el número de inodo del archivo del
content_view let_
directorio de archivo /etc como su único símbolo.
Sugerencias
Las primeras líneas del archivo etc.bytime deberían verse de la siguiente manera, aunque los
detalles (tal como la última modificación) pueden diferir.
total 2716
-rw-r--r-- 1 root root 258 May 21 09:27 mtab
-rw-r--r-- 1 root root 699 May 21 09:13 printcap
-rw-r----- 1 root smmsp 12288 May 21 09:10 aliases.db
-rw-rw-r-- 2 root root 107 May 21 09:10 resolv.conf
-rw-r--r-- 1 root root 28 May 21 09:10 yp.conf
-rw------- 1 root root 60 May 21 09:10 ioctl.save
-rw-r----- 1 root root 1 May 21 09:10 lvmtab
drwxr-xr-x 2 root root 4096 May 21 09:10 lvmtab.d
-rw-r--r-- 1 root root 46 May 21 08:55 adjtime
75
Enlaces duros y blandos
Conceptos clave
Discussion
En ocasiones, los usuarios de Linux quieren que el mismo archivo exista en dos lugares diferentes
o que tengan dos nombres diferentes. Un método es crear un enlace duro.
Suponga que elvis y blondie están colaborando en un dueto. A ellos les gustaría poder trabajar en
la letra de las canciones si el tiempo les permite y poder beneficiarse del trabajo uno del otro. En
lugar de copiar un archivo actualizado de cada uno, cada vez que hacen un cambio y mantener sus
copias individuales sincronizadas, deciden crear un enlace duro.
Debido a que el archivo fue enlazado y no copiado, es el mismo archivo bajo dos nombres. Cuando
elvis edita /home/elvis/music/duet.txt está editando también el archivo /home/blondie/music/duet.txt.
76
Figure 1. Archivo regular
Después de usar el comando ln para crear el enlace, el archivo es todavía un sólo inodo, pero
ahora hay dos dentries refiriéndose a éste.
Cuando blondie ejecuta el comando ls -l, examina detenidamente en la segunda columna, la cual
reporta el conteo de enlace para el archivo.
Hasta ahora, no hemos prestado atención al conteo de enlaces y casi siempre ha sido 1 para
archivos regulares (implicando una dentry que hace referencia a un inodo). Sin embargo, ahora,
dos dentries hacen referencia al inodo y el archivo tiene un conteo de enlace 2. Si blondie cambia
los permisos en el archivo /home/blondie/music/duet.txt, ¿qué sucede al archivo /home/elvis/music/
duet.txt?
77
[elvis@station elvis]$ ls -l music/duet.txt
-rw-rw---- 2 blondie music 25 Jul 13 06:08 music/duet.txt
Puesto que ambas partes del enlace comparten el mismo inodo, elvis también ve los permisos
cambiados.
¿Cómo esperaría que fuera ahora el conteo de enlaces del archivo /home/elvis/music/duet.txt?
Un poco incómodo, elvis se ha quedado con un archivo de blondie, no obstante, aún es un archivo
válido. En un nivel bajo, el comando rm no borra un archivo, sino que lo "desenlaza". Un archivo
(es decir, el inodo de archivo y los datos) se borran automáticamente desde el sistema cuando su
conteo de enlace va hasta 0 (lo que implica que no hay más dentries (nombres de archivo)
haciendo referencia al archivo).
Al otro método para asignar dos nombres a un archivo único se le denomina un enlace blando.
Aunque de modo superficial son similares, los enlaces blandos se implementan de una manera
muy diferente a la de los enlaces duros.
La usuaria madonna es muy organizada y ha agrupado sus tareas en siete listas, una para cada
día de la semana.
78
[madonna@station madonna]$ ls todo/
friday.todo saturday.todo thursday.todo wednesday.todo
monday.todo sunday.todo tuesday.todo
Consulta la lista varias veces al día, pero nota que le cuesta trabajo recordar qué día de la semana
es hoy. Preferiría tener un archivo único llamado today.todo que se actualice cada mañana. Decide
utilizar un enlace blando en su lugar. Debido a que hoy es martes (Tuesday en inglés), usa el
mismo comando ln utilizado para crear enlaces duros, pero agrega la opción de línea de comando
-s para especificar el enlace blando.
[madonna@station todo]$ ls
friday.todo saturday.todo thursday.todo wednesday.todo
monday.todo sunday.todo tuesday.todo
[madonna@station todo]$ ln -s tuesday.todo today.todo
[madonna@station todo]$ ls -l
total 32
-rw-rw-r-- 1 madonna madonna 138 Jul 14 09:54 friday.todo
-rw-rw-r-- 1 madonna madonna 29 Jul 14 09:54 monday.todo
-rw-rw-r-- 1 madonna madonna 579 Jul 14 09:54 saturday.todo
-rw-rw-r-- 1 madonna madonna 252 Jul 14 09:54 sunday.todo
-rw-rw-r-- 1 madonna madonna 519 Jul 14 09:54 thursday.todo
lrwxrwxrwx 1 madonna madonna 12 Jul 14 09:55 today.todo ->
tuesday.todo
-rw-rw-r-- 1 madonna madonna 37 Jul 14 09:54 tuesday.todo
-rw-rw-r-- 1 madonna madonna 6587 Jul 14 09:55 wednesday.todo
Examine de cerca el tipo de archivo (el primer caracter de cada línea en el comando ls -l) del
archivo recién creado today.todo. Este no es un archivo regular ("-"), ni un directorio ("d"), sino un
"l", indicando un enlace simbólico. Un enlace simbólico, también denominado enlace "blando", es
un archivo que hace referencia a otro archivo por nombre de archivo. Los enlaces blandos son
similares a alias encontrados en otros sistemas operativos. Afortunadamente, el comando ls -l
también muestra a qué archivo el enlace blando hace referencia, donde today.todo -> tuesday.todo
implica el enlace blando denominado today.todo hace referencia al archivo tuesday.todo.
Ahora, cada vez que madonna haga referencia al archivo today.todo, estará en realidad
examinando el archivotuesday.todo.
¿Cómo se implementan los enlaces blandos? Al ser creado, el archivotuesday.txt, igual que la
mayoría de archivos, consta de una dentry, un inodo, y datos, como se ilustra en la parte de abajo.
Cuando el enlace blando today.txt fue creado, el enlace blando (a diferencia del enlace duro) es en
79
realidad un archivo nuevo, con un inodo recién creado. Sin embargo, el enlace no es un archivo
regular, sino un enlace simbólico. Los enlaces simbólicos, en lugar de almacenar datos reales,
almacenan el nombre de otro archivo. Cuando se le pide al kernel de Linux referirse a los enlaces
simbólicos, el kernel automáticamente apunta al enlace buscando el nuevo nombre de archivo. El
usuario (o en realidad, el proceso en nombre del usuario) que hizo referencia al enlace simbólico
no conoce la diferencia.
Como se ilustró anteriormente, tanto los enlaces duros como los blandos se crean con el comando
ln.
Opción Efecto
-f, --force sobrescribir archivos de destino existentes
-s, --symbolic hacer un enlace simbólico (blando) en lugar de un enlace duro
80
el orden primero no genera los resultados esperados.Otra vez, cuando tenga alguna duda,
recuerde la conducta del comandocp.
En el siguiente ejemplo corto, madonna crea el archivo orig.txt. Luego trata de hacer un enlace
duro para éste llamado newlnk.txt, pero obtiene el orden de los argumentos incorrectamente.
Dándose cuenta del error, corrige el problema.
Enlaces colgantes
Los enlaces blandos son susceptibles a un par de problemas que los enlaces duros no tienen. El
primero se llama enlaces colgantes. ¿Qué sucede si madonna renombra o suprime el archivo
tuesday.todo?
El enlace simbólico today.todo aún hace referencia al archivo tuesday.todo, pero el archivo
tuesday.todo ¡ya no existe! Cuando madonna trata de leer el contenido de today.todo, encuentra un
error.
81
Enlaces recursivos
En segundo lugar, los enlaces simbólicos son susceptibles a los enlaces recursivos. En el uso
diario, los enlaces recursivos no son tan comunes como los enlaces colgantes, y alguien casi que
tiene que buscarlos para poder crearlos. ¿Qué sucede si alguien tiene que estar buscándolos para
crearlos? ¿Qué ocurre si madonna crea dos enlaces simbólicos, link_a, que hagan referencia a un
archivo llamado link_b, ylink_b, el cual hace referencia al archivo link_a, como se ilustra a
continuación?
Cuando madonna trata de leer el archivo link_a, el kernel apunta al enlace _a para enlazar_b, el
cual luego vuelve a apuntar al enlace _a y así sucesivamente. Afortunadamente, el kernel solo
82
apuntará a un enlace muchas veces antes de sospechar de que se encuentra en un enlace
recursivo, y desiste.
Al crear enlaces blandos, los usuarios pueden elegir entre especificar el enlace del destino
mediante una referencia relativa o absoluta. Si el enlace blando y su destino, nunca van a ser
reubicados la opción no importa. Sin embargo, los usuarios a menudo no pueden prever cómo se
van a utilizar en el futuro los archivos que crean. Normalmente, los enlaces relativos son más
resistentes a cambios inesperados.
¿Cuándo debería utilizarse un enlace blando y cuándo un enlace duro? Generalmente, los enlaces
duros son más apropiados si ambas instancias del enlace tienen un uso razonable, incluso si la
otra instancia no existiera. En el ejemplo anterior, incluso si blondie decidiera no trabajar en el
dueto y removiera el archivo, elvis podría continuar trabajando razonablemente sin el otro archivo.
En el ejemplo anterior, madonna no hubiera podido tener tareas para "today" si no hubiera tenido
para "tuesday". Estos lineamientos generales, sin embargo, no endurecen ni agilizan las reglas.
Algunas veces, restricciones más prácticas escogen de una manera más fácil entre enlaces duros
y blandos. A continuación, se muestran algunas diferencias entre los enlaces duros y blandos. No
se preocupe si no entiende los dos últimos puntos, estos se mencionan aquí para completar la
información proveída.
83
Ejemplos
En su directorio de inicio, blondie tiene un archivo llamado rhyme y un directorio llamado stuff. Ella
hace un listado largo con el comando ls -li, donde la opción -i hace que el comandols imprima el
número de inodos de cada archivo como la primera columna de la salida.
Puesto que cada inodo en un sistema de archivos tiene un número único de inodos, el número de
inodos que se puede utilizar para identificar un archivo. De hecho, cuando se lleve el rastro de
archivos internamente, el kernel suele referirse al archivo más por el número de inodo que por
nombre de archivo.
Ella crea un enlace duro en el archivo rhyme y ve el contenido del directorio una vez más.
El conteo de enlaces para rhyme ahora es 2. Además, observe que el número de inodos tanto para
rhyme como para hard_link es 246085, lo que implica que, aunque hay dos nombres para el
archivo (dos dentries) hay un sólo inodo.
Si cambiamos los permisos en rhyme, los permisos en hard_link también cambiarán. ¿Por qué? los
dos nombres de archivo se refieren al mismo inodo. Puesto que el inodo hace referencia al
contenido de un archivo, también comparten los mismos datos.
84
Mover o incluso suprimir el archivo original no tiene efecto en el archivo de enlace.
./stuff:
total 4
246085 -rw-rw---- 2 blondie blondie 51 Jul 18 15:29 rhyme
La usuaria blondie ahora repite el mismo ejercicio, pero utiliza un enlace blando en lugar de uno
duro. Comienza con una configuración idéntica a la del ejemplo anterior.
Ahora crea un enlace blando en el archivo rhyme y ve el contenido del directorio otra vez.
A diferencia del enlace duro del ejemplo anterior, el enlace blando existe como un inodo distinto
(con un número de inodo distinto) y el conteo de enlaces de cada uno de los archivos permanece
en 1. Lo que implica que ahora hay dos dentries y dos inodos. Cuando se hace referencia, sin
embargo, los archivos se comportan de una manera idéntica al caso de los enlaces duros.
A diferencia del enlace duro, el enlace blando no puede sobrevivir si se mueve o suprime el archivo
original. En cambio, blondie queda con el enlace colgante.
85
[blondie@station blondie]$ ls -liR
.:
total 4
250186 lrwxrwxrwx 1 blondie blondie 5 Jul 18 15:26 soft_link -> rhyme
542526 drwxrwxr-x 2 blondie blondie 4096 Jul 18 15:31 stuff
./stuff:
total 4
246085 -rw-rw-r-- 1 blondie blondie 51 Jul 18 15:29 rhyme
[blondie@station blondie]$ cat soft_link
cat: soft_link: No such file or directory
Los enlaces blandos también son útiles como punteros en directorios. Los enlaces duros sólo se
pueden utilizar con archivos ordinarios.
El usuario einstein ahora puede fácilmente cambiarse a los documentos del directorio sin tener que
recordar o teclear la ruta absoluta larga.
Ejercicios en línea
Crear y administrar listas Lab Exercise Objetivo: Crear y administrar enlaces duros y
blandosEstimated Time: 10 mins.
Especificaciones
86
Si ha terminado el ejercicio correctamente, debería poder reproducir una salida similar a la
siguiente.
[student@station student]$ ls -l
total 12
-rw-rw-r-- 2 student student 138 Jul 21 10:03 cal.harda
-rw-rw-r-- 2 student student 138 Jul 21 10:03 cal.hardb
lrwxrwxrwx 1 student student 8 Jul 21 10:03 cal.softa -> cal.orig
lrwxrwxrwx 1 student student 14 Jul 21 10:03 docabs -> /usr/share/doc
lrwxrwxrwx 1 student student 19 Jul 21 10:03 docrel ->
../../usr/share/doc
Compartir un archivo de enlace duro Objetivo: Compartir un archivo de enlace duro entre dos
usuarios.
Especificaciones
Usted desearía crear un archivo de enlace duro que le permita compartir con otro usuario.
1. Como usuario primario, crea un subdirectorio /tmp llamado como su nombre de cuenta,
como por ejemplo /tmp/student, donde student es remplazado por su nombre de usuario.
2. Todavía como su usuario primario, cree un archivo llamado /tmp/student/novel.txt que
contenga el texto "Once upon a time."
87
archivo cambiando la línea desde "Once upon a time,", hasta "It was a dark and stormy
night.". ¿Por qué tuvo problemas? ¿Puede modificar las propiedades o permisos del
archivo novel.lnk? ¿Por qué sí o por qué no?
content_view let_
88
Directorios y nodos de dispositivo
Conceptos clave
Discussion
Directorios
Al comienzo, presentamos dos estructuras asociadas con los archivos, dentries que asocian
nombres de archivos con inodos e inodos, que asocian todos los atributos de un archivo con su
contexto. Ahora veremos cómo se relacionan estas estructuras con los directorios.
El usuario prince está usando un directorio llamado report para administrar archivos de un informe
que está escribiendo. De modo recursivo lista el directorio report, incluyendo -a (el cual especifica
listar "todas"las entradas, incluyendo los que comienzan por un ".") y el comando -i (el cual
especifica listar el número de inodos de un archivo así como el nombre del archivo). Lo que resulta
es el siguiente listado de directorios y archivos, junto con su número de inodos.
report/html:
592255 . 592253 .. 592261 chap1.html 592262 chap2.html 592263 figures
report/html/figures:
592263 . 592255 .. 592264 image1.png
report/text:
592254 . 592253 .. 592257 chap1.txt 592258 chap2.txt
Observe que los archivos (directorios) ".".y ".."están incluídos en la salida. Como se mencionó en
un cuaderno anterior, el directorio "."se refiere al directorio mismo y el directorio ".."se refiere al
directorio padre. Cada directorio en realidad contiene entradas denominadas . y.., aunque sean
tratadas como archivos ocultos (debido a que "comienzan por ."), no se visualizan a no ser que se
especifique el comando -a.
89
Los mismos directorios, archivos y números de inodo se reproducen abajo en un formato más fácil.
path | inode
--------------------------------------------
report/ | 592253
|-- html | 592255
| |-- chap1.html | 592261
| |-- chap2.html | 592262
| `-- figures | 592263
| `-- image1.png | 592264
`-- text | 592254
|-- chap1.txt | 592257
`-- chap2.txt | 592258
Como se puede ver en la siguiente gráfica del directorio report, los directorios tienen la misma
estructura de los archivos regulares: una dentry, un inodo, y datos. No obstante, los datos
almacenados en los directorios, son las dentries asociadas con los archivos de directorio que se
dice que contienen. Un directorio es un poco más que un cuadro de dentries, asignando nombres
de archivo as los inodos subyacentes que representan archivos. Cuando fue presentado, el nombre
dentry se decía que se derivaba de directoryentry. Ahora vemos que los directorios no son más
complicados que eso: un directorio es una colección de dentries.
Enlaces de directorios
90
Anteriormente vimos que el conteo de enlaces de directorios, como se muestra en la segunda
columna del comando ls -l, fue siempre 2 o más. Esto se deduce naturalmente del hecho que cada
directorio se referencia al menos dos veces, una por sí mismos (como el "."), y otra como su padre
(con un nombre de directorio real, tal como report). El siguiente diagrama sirve de ilustración de las
dentries que se encuentran en el directorio report , su subdirectorio html, y su subdirectorio figures).
Cuando prince hace un listado largo del directorioreport, ve los cuatro archivos en el primer cuadro.
Cada archivo en el listado es un directorio y el conteo de enlaces (aquí la tercera columna, ya que
el numero de inodos ha sido adjuntado con antelación en la primera columna) de cada uno es o
igual o mayor de dos. ¿Podemos responder por cada uno de los enlaces? Comencemos por listar
las referencias al número de inodo 592253 (el directorio report o el anterior ".").
91
3. El subdirectorio html contiene una entrada llamada.., la cual hace referencia al inodo
592253 como su directorio padre.
4. Del mismo modo, el subdirectorio text (no descrito) contiene una entrada llamada .. que
hace referencia al mismo inodo.
Respondiendo por si mismo (al cual llama "."), su padre (al cual llama"report"), y sus dos
subdirectorios (a los cuales llama ".."), hemos hallado todos nuestros enlaces en el inodo 592253
reportados por el comando ls -l.
En resumen, los directorios son simplemente colecciones de dentries para los archivos que se dice
que están en el directorio, los cuales asignan los nombres de archivo a los inodos. Cada directorio
contiene al menos dos enlaces, uno desde su propia entrada de directorio ".", y otro desde su
entrada padre con el nombre convencional del directorio. Se hace referencia a los directorios por
un enlace adicional para cada subdirectorio, los cuales hacen referencia al directorio como "..".
Nodos de dispositivo
Hemos analizado tres tipos de "criaturas" que pueden existir en el sistema de archivos de Linux, es
decir los archivos regulares, los directorios y los enlaces simbólicos. En esta sección, discutiremos
los dos últimos tipos de entradas del sistema de archivos (que se tratarán en este curso), nodos de
dispositivo de bloque y de caracter.
Los nodos de dispositivos existen en el sistema de archivos, pero no contienen datos de la misma
forma que los archivos regulares o incluso los directorios y enlaces simbólicos. En su lugar, la labor
de un dispositivo de nodo es actuar como un conducto hacia un controlador de dispositivo
determinado dentro del kernel. Cuando el usuario escribe en el nodo del dispositivo, el nodo del
dispositivo transfiere la información al controlador de dispositivo apropiado en el kernel. Cuando un
usuario desea recopilar información desde un dispositivo particular, se lee desde ese nodo de
dispositivo asociado con el dispositivo justo como si leyera desde un archivo.
Por convención, los nodos de dispositivo viven dentro de un directorio llamado /dev. A continuación
el usuario elvis hace un listado largo de archivos en el directorio /dev.
92
[elvis@station elvis]$ ls -l /dev
total 228
crw------- 1 root root 10, 10 Jan 30 05:24 adbmouse
crw-r--r-- 1 root root 10, 175 Jan 30 05:24 agpgart
crw------- 1 root root 10, 4 Jan 30 05:24 amigamouse
...
crw------- 1 elvis root 14, 7 Jan 30 05:24 audioctl
brw-rw---- 1 root disk 29, 0 Jan 30 05:24 aztcd
crw------- 1 elvis root 10, 128 Jan 30 05:24 beep
brw-rw---- 1 root disk 41, 0 Jan 30 05:24 bpcd
crw------- 1 root root 68, 0 Jan 30 05:24 capi20
Como hay más de7000 entradas en el directorio /dev, la salida se limita sólo a los primeros
archivos. Enfocándonos en el primer caracter de cada línea, la mayoría de los archivos dentro de
/dev no son archivos regulares o directorios, sino nodos de dispositivo de caracter ("c"), o nodos de
dispositivos de bloque ("b"). Los dos tipos de nodos de dispositivos reflejan el hecho de que los
controladores de dispositivos en Linux se dividen en dos clases principales: los dispositivos de
caracter y los dispositivos de bloque.
Dispositivos de Caracter
Los dispositivos de caracter son dispositivos que leen y escriben información como un flujo
de bytes ("caracteres"), y hay un concepto natural de lo que significa leer o escribir el
"próximo " caracter. Ejemplos de dispositivos de caracter incluyen teclado, ratón. tarjetas
de sonido e impresoras.
Dispositivos de bloque
Los dispositivos de bloque son dispositivos que leen y escriben información en fragmentos
("bloques") a la vez. Es costumbre que los dispositivos de bloque permitan acceso
aleatorio, lo que significa que un bloque de datos podría leerse desde cualquier parte del
dispositivo, en cualquier orden. Ejemplos de dispositivos de bloque incluyen, discos duros,
disquetes y controladores de CD/ROM.
En el siguiente ejemplo, elvis ha iniciado sesión en una máquina de Linux, en la primera y segunda
consola virtual. En el primer cuaderno, vimos la manera de identificar terminales por nombre y
hallamos que el nombre de la primera consola era tty1, y la segunda consola virtual era tty2. Ahora,
podemos ver que el "nombre" de la terminal es en realidad el nombre del nodo de dispositivo
asignado a esa terminal. En el listado siguiente, los nodos de dispositivo /dev/tty1 a través de
/dev/tty6 son los nodos de dispositivo para las primeras 6 consolas virtuales, respectivamente.
93
En el siguiente ejemplo, elvis, está trabajando desde la consola virtual número 1, y redirigirá tres
veces la salida del comando cal, primero, a un archivo llamado /tmp/cal, segundo, a un nodo de
dispositivo /dev/tty1 y por último, al nodo de dispositivo /dev/tty2.
Este caso debería ser familiar, la salida simplemente se redirige al archivo recién creado cal.
Aparentemente, no se pudo redirigir, pero sí lo hizo. La salida del comando fue redirigida al
nodo del dispositivo de la primera consola virtual, el cual hizo lo que se "suponía que tenía
que hacer", es decir, mostrar toda la información escrita en la pantalla.
¿A dónde va la salida del comando cal esta vez? La información fue redirigida al nodo de
dispositivo para la segunda consola virtual, lo cual hizo lo que se "suponía que debía hacer",
es decir, mostrarla en la segunda consola virtual.
La segunda forma de redirigir amerita un poco más de atención. Cuando elvis redirigió la salida al
nodo de dispositivo que controla su consola virtual actual, /dev/tty1, pareció no haber redirigido
nada en absoluto. ¿Por qué? Cuando elvis ejecuta comandos interactivos sin redirigir, escriben en
los nodos de dispositivo que controlan las terminales por defecto. Redirigir la salida de comando a /
dev/tty1 es como decir "en lugar de escribir su salida en mi terminal, escriba su salida en mi
terminal."
Al cambiar a la segunda consola virtual, utilizando la secuencia de teclas CTRL-ALT-F2, elvis halla
los siguientes caracteres en la pantalla.
Aquí es donde estaba el cursor de elvis después de iniciar sesión en la segunda consola
virtual y cambiar a la consola virtual número 1.
Aquí es donde la salida del comando cal estaba escrita en la terminal. Observe la falta de
94
espacios separando la salida. Esta no es una ocurrencia natural con buen formato, sino algo
extraño que elvis le pidió hacer al controlador del dispositivo.
Por último, la salida del comando cal disminuyó, pero observe que bash shell no ofrece un
intérprete de comandos fresco. De hecho, la shell bash ni siquiera se dio cuenta que los
caracteres fueron escritos en la terminal. Aún está esperando que elvis entre el comando.
Continuando con lo anterior, el usuario elvis (quien ha iniciado sesión en las primeras dos consolas
virtuales, filename>tty1
¿Por que elvis no pudo realizar el mismo truco en la tercera consola virtual? Porque elvis no ha
iniciado sesión en la tercera consola virtual y por lo tanto, no posee el dispositivo. Examine de
nuevo el listado largo de comandos ls -l de los nodos de dispositivo de la consola virtual:
Puesto que los nodos de dispositivo se consideran archivos, también tienen usuarios propietarios,
grupo propietarios y una colección de permisos. Al leer o escribir desde el nodo de dispositivo
aplica solo como si leyera o escribiera a un archivo regular. Esto le permite a un administrador de
sistemas (o al software en el sistema) controlar quién ha tenido acceso a los dispositivos
particulares mediante una técnica familiar, es decir, administrando los propietarios de archivo y los
permisos de archivo.
Cuando un usuario inicia sesión, se obtiene propiedad del nodo de dispositivo que controla su
terminal. Los procesos que ellos ejecutan pueden luego leer o escribir salida en la terminal. En
general, los permisos en los nodos de dispositivos no permiten a los usuarios estándares acceder a
los dispositivos directamente. Hay dos excepciones.
95
Terminales
Puesto que los usuarios necesitan comunicarse con el sistema, ellos (o más exactamente,
los procesos que ellos ejecutan) deben ser capaces de leer y escribir en la terminal que
están usando. Suele presentarse que parte del proceso de inicio de sesión en un sistema
implica la transferencia de propiedad de nodos de dispositivos de terminal al usuario.
"Usuarios de Consola"
En Red Hat Enterprise Linux, a los usuarios se les otorgan permisos no por quiénes son,
sino por desde dónde se ha iniciado la sesion. Es decir, cuando un usuario inicia sesión en
una consola virtual o en un servidor gráfico X, se considera un "usuario de consola". Los
usuarios de consola tienen acceso a dispositivos de hardware asociados con la consola,
tales como disquetes y tarjetas de sonido. Cuando los usuarios de consola terminan
sesión, las propiedades para estos dispositivos son restauradas a las predeterminadas del
sistema, Nada de esto sucede si un usuario inicia sesión en una red, por ejemplo. -Si el
usuario no está en la máquina, ¿sería razonable usar disquetes?
En resumen, Linux (y UNIX) utilizan los nodos de dispositivo para permitir a los usuarios el acceso
a dispositivos en el sistema. La administración de dispositivos en un sistema de Linux puede ser un
tema extenso y complejo. A manera de introducción, hemos visto suficiente acerca de cómo se
utilizan los nodos de dispositivo de la terminal para presentar el concepto e identificar un par de
ventajas en el enfoque del nodo de dispositivo.
Ejemplos
El usuario elvis hace un listado largo del directorio /var/spool. Está interesado en interpretar el
conteo de enlaces del subdirectorio como aparece en la segunda columna.
96
Al notar que tiene un conteo de enlaces de 17, elvis concluye que el directoriopostfix contiene 15
subdirectorios. 1 enlace como se muestra arriba para la entrada postfix , 1 enlace para la entrada .
que se encuentra dentro de postfix (no se muestra) y 15 para las entradas .. dentro de 15
subdirectorios.
Al examinar un listado largo del directorio/var/spool/postfix, concluye que estaba en lo cierto (hay
15 subdirectorios).
97
Discos, sistemas de archivos y montaje
Conceptos clave
• Linux permite el acceso de bajo nivel a los controladores de disco a través de nodos de
dispositivo en el directorio /dev.
• Por lo general, los discos se formatean con un sistema de archivos y se montan en un
directorio.
• Los sistemas de archivos se crean con algunas variantes del comando mkfs.
• El sistema de archivos predetermiando de Red Hat Enterprise Linux es el sistema de
archivos ext3.
• El comando mount se utiliza para asignar el directorio root de un sistema de archivos (o
una partición de un disco) a un directorio ya existente. Ese directorio se denomina punto
de montaje.
• El comando umount se utiliza para desmontar un sistema de archivos de un punto de
montaje.
• El comando df se utiliza para reportar el uso del sistema de archivos y mapea los
dispositivos actualmente montados.
Discussion
Dispositivos de disco
Linux (y Unix) permite a los usuarios acceso directo, de bajo nivel a los controladores de disco a
través de los nodos de dispositivos en el directorio /dev. El siguiente cuadro lista los nombres de
archivos de los nodos de dispositivos comunes y los discos con los cuales están asociados.
Aunque los nodos de dispositivo existen para los controladores de disco, los usuarios estándar no
suelen tener permisos de acceso directo. A continuación elvis ha realizado un listado largo de
varios nodos de dispositivo que aparecen en el cuadro anterior.
98
[elvis@station elvis]$ ls -l /dev/fd0 /dev/hd[abcd] /dev/sda /dev/cdrom
lrwxrwxrwx 1 root root 8 Oct 1 2002 /dev/cdrom ->
/dev/hdc
brw-rw---- 1 elvis floppy 2, 0 Jan 30 05:24 /dev/fd0
brw-rw---- 1 root disk 3, 0 Jan 30 05:24 /dev/hda
brw-rw---- 1 root disk 3, 64 Jan 30 05:24 /dev/hdb
brw------- 1 elvis disk 22, 0 Jan 30 05:24 /dev/hdc
brw-rw---- 1 root disk 22, 64 Jan 30 05:24 /dev/hdd
brw-rw---- 1 root disk 8, 0 Jan 30 05:24 /dev/sda
Por defecto, elvis no tiene permisos para acceder a los controladores fijos de la máquina. Dado que
(aparentemente) está conectado en la consola, se considera el "usuario de la consola" y ha ganado
permisos para acceder a los disquetes y al CD/ROM. Aprovecharemos este hecho durante esta
lección.
Los discos duros suelen dividirse en particiones. Las particiones son regiones del disco duro que
se pueden utilizar como si cada una fuera un disco individual. Así como hay nodos de dispositivo
para cada disco, los hay también para cada partición de disco. El nombre de una partición de nodo
de dispositivo es simplemente un número adjunto al nombre de nodo de dispositivo del disco. Por
ejemplo, el nodo de dispositivo para la tercera partición del controlador IDE esclavo primario se
denomina /dev/hdb3.
El siguiente diagrama ilustra un disco duro que se ha dividido en cuatro particiones y los nodos de
dispositivo dirigidos a cada una de ellas.
A continuación, elvis está explorando el acceso al nivel bajo para su disquete. Comienza por
asegurarse si tiene permisos de lectura y escritura en su nodo de dispositivo del disquete
ejecutando cat en el archivo /etc/resolv.conf y luego redirigiendo la salida del comando al
controlador del disquete (/dev/fd0).
99
[elvis@station elvis]$ ls -l /dev/fd0
brw-rw---- 1 elvis floppy 2, 0 Jan 30 05:24 /dev/fd0
[elvis@station elvis]$ cat /etc/resolv.conf
search example.com
nameserver 192.168.0.254
[elvis@station elvis]$ cat /etc/resolv.conf > /dev/fd0
-bash: /dev/fd0: No such device or address
En un comienzo, perplejo por el mensaje de error, elvis nota que no hay disquete en su controlador
de disquete. Coloca un disco antiguo en blanco (para no preocuparse del contenido) en el
controlador.
Perplejo de nuevo, elvis quita el disquete del controlador, lo examina, desliza la lengüeta del
disquete a la posición de escritura e inserta de nuevo el disquete.
Finalmente, la luz del controlador del disquete se alumbra y elvis escucha al disco dando vueltas
porque hay información en el disquete. Curioso por ver lo que ha escrito en el disquete, trata luego
de leerlo con el paginador less.
El paginador less parece estarle diciendo a elvis, "La gente cuerda no lee los nodos de dispositivo
directamente, pero si realmente quiere hacerlo, yo se lo permito." Como realmente quiere hacerlo,
agrega la opción -f.
search example.com
nameserver 192.168.0.254
B^RA^^@^@V^^|F^@^@^@AdDBP^A^^|^C^F^B|^@DVP|Q^^^R ABAoot
failed^@^@^@LDLINUX SYS
...
El usuario elvis continua a través del "archivo" usando el paginador less, viendo aparentemente
pedazos de texto aleatorios y caracteres binarios. Cuando cree que lo logra, abandona el
paginador.
100
¿Para qué todo esto? Al acceder a los controladores de disco a través de sus nodos de dispositivo,
los usuarios pueden ver (y escribir) el contenido del controladorbyte por byte. Para el usuario, el
controlador se ve como un archivo bien grande. Cuando elvis hace cat en el contenido de un
archivo al nodo de dispositivo del controlador, la información es transferida, byte por byte al
controlador.
En los primeros bytes del disquete, elvis ve una copia del contenido del archivo /etc/resolv.conf.
¿Cuál es el nombre de archivo asociado con la información, en el disquete? Pregunta delicada. No
tiene . ¿Quién es el usuario propietario? ¿Cuáles son los permisos?No hay ninguno. Es sólo datos.
Cuando elvis va atrás para leer el contenido del controlador, ve los datos que escribió allí, es decir,
el contenido del archivo /etc/resolv.conf. Después de eso, ve lo que habia en el disquete antes de
iniciar.
Sistemas de archivos
La sección anterior demostró la manera de acceder a los controladores en un nivel bajo. Es obvio
que la gente no le gusta almacenar su información en controladores como un flujo de datos. A ellos
les gusta organizar su información en archivos y darle nombres a los archivos. A ellos les gusta
organizar sus archivos en directorios y decir quién puede tener acceso al directorio y quién no.
Toda esta estructuración de información es responsabilidad de lo que se denomina un sistema de
archivos.
Antes de que un disco se pueda utilizar para almacenar archivos en el sentido convencional , se
debe ser inicializar con este tipo de estructura de bajo nivel. En Linux, se denomina una "creación
de un sistema de archivos". En otros sistemas operativos, se suele referir como "formatear el
disco". Linux soporta un gran número de tipos diferentes de sistemas de archivos (la página del
manual fs(5) lista apenas unos pocos). Aunque el sistema de archivos nativo de Linux es ext2 (o en
Red Hat Enterprise Linux, ext3), también es compatible con los sistemas de archivo nativos de
muchos sistemas operativos tales como el sistema de archivos DOS FAT o el sistema de archivos
de alta ejecución OS/2.
En Linux, los sistemas de archivos se crean con algunas variantes del comando mkfs. Dado que
estos comandos se suelen utilizar solamente por el usuario administrativo, no viven en los
directorios estándar /bin ni en el directorio /usr/bin, por lo tanto no pueden invocarse como simples
comandos. En cambio, viven en el directorio /sbin, el cual está reservado para los comandos
administrativos. A continuación, elvis lista todos los comandos que comienzan por mkfs en el
directorio /sbin.
101
Aparentemente, hay una copia del comando mkfs por cada tipo de sistema de archivo que se
puede construir, incluyendo los sistemas de archivos ext2 y msdos. El usuario elvis luego formatea
el mismo disco utilizado anteriormente con el sistema de archivo ext2. Dado que el comando
mkfs.ext2 no vivió en uno de los directorios "estándar", elvis necesita referirse al comando
mediante una referencia absoluta, /sbin/mkfs.ext2.
El comando mkfs.ext2 muestra información acerca del sistema de archivos a medida que se crea
en el dispositivo /dev/fd0. Cuando el comando completa, el sistema de archivo ha sido inicializado y
el disquete está listo para ser utilizado.
El comando mkfs y sus variantes, pueden configurarse con una gran colección de líneas de
opciones, las cuales especifican detalles del nivel bajo acerca del sistema de archivos. Estos
detalles van más allá del objetivo de este curso. Afortunadamente, las diversas opciones se
predeterminan para propósitos generales por defecto. Encontrará mayor información en las
páginas del manual mkfs.ext2(8) y similares.
Una vez se le ha dado formato al disco o a la partición del disco con el sistema de archivos, los
usuarios necesitan alguna forma de acceder los directorios y los archivos que el sistema de
archivos provee. En otros sistemas operativos, los usuarios suelen ser mas conscientes de la
particiones de disco porque tienen que referirse a ellos mediante etiquetas tales como C: o D:. En
Unix, los usuarios suelen no darse cuenta de las particiones porque las diferentes particiones de
disco están organizadas en una estructura única de directorio.
¿Cómo se hace esto? Cada sistema de archivos proporciona un directorio raíz que sirve como
base de este sistema de archivos. Una vez se haya iniciado el sistema, una de sus particiones de
discos actúa como la partición raíz y su directorio raíz se convierte en el directorio raíz del sistema
/. Algunas veces, este es el final de la historia. El directorio / tiene subdirectorios y esos
subdirectorios tienen subdirectorios, los cuales residen en el sistema de archivo de la partición raiz.
Sin embargo, si un sistema tiene múltiples discos, o si un disco tiene múltiples particiones, las
cosas se complican. Con el fin de acceder a los sistemas de archivos en las otras particiones, los
102
directorios raíz de aquellos sistemas se asignan a un directorio existente a través de una técnica
estándar de Unix llamada montaje.
Ahora, todas las referencias al directorio /home se asignan de un modo transparente al directorio
raíz del sistema de archivos en /dev/hda4, dando la apariencia que el directorio /home contiene los
subdirectorios blondie, elvis, etc, como se muestra a continuación. Cuando el sistema de archivos
se monta sobre un directorio de esta manera, dicho directorio se denomina punto de montaje.
¿Cómo puede elvis saber qué partición contiene un archivo determinado? Usando sólo el comando
ls¡no puede! Para ejecutar el comando ls y usualmente en la mente del usuario, todas las
particiones se combinan correctamente dentro de una aparente única estructura de directorio.
¿Cómo puede un usuario determinar qué directorios se están usandos como puntos de montaje?
Un método es ejecutar el comando mount sin argumentos.
103
Sin argumentos, el comando mount devuelve una lista de puntos de montaje, el dispositivo que
está montado a ésta, el tipo de sistema de archivos con el que el dispositivo le ha dado formato y
cualquier otra opción de montaje asociadas con el montaje. En el ejemplo anterior, la partición /dev/
hda3 se está utilizando como partición raíz y el sistema de archivo ext3 en la partición /dev/hda1 ha
sido montado en el directorio /boot. Observe que varios sistemas de archivos listados arriba no
tienen "ningún" dispositivo. Estos son sistemas de archivos virtuales, los cuales son implementados
por el kernel directamente y no existen en ningún dispositivo físico.
Si rara vez usted sabe qué directorios se están utilizando como puntos de montaje y qué archivos
existen en las particiones, ¿para que molestarse incluso por hablar de esto? Por ahora, daremos
dos razones. La primera razón es que pueden haber problemas sutiles, que pueden empeorar,
relacionados con el sistema de archivos subyacente. A las particiones se les puede acabar el
espacio. Si a un archivo montado en /home se le acaba el espacio, no se pueden crear más
archivos bajo el directorio/home. Sin embargo, esto no afecta al directorio /tmp porque éste
pertenece a otro sistema de archivos. En Unix, cuando una partición se llena, sólo afecta a la parte
de la estructura del directorio bajo su punto de montaje, no a todo el árbol de directorios.
Los usuarios pueden determinar cuánto espacio está disponible en una partición con el comando
df, el cual significa "disk free".
df [OPCIÓN...] [ARCHIVO...]
Muestra información sobre todas las particiones o una partición en la cuales reside un ARCHIVO.
Opción Efecto
-a, --all Muestra todos los sistemas de archivos, incluyendo aquellos de tamaño
0.
-h, --leíble por Imprime tamaños en formato legible por humanos
humanos
-i, --inodes Lista el uso de inodos en lugar del uso del bloques
-T, --print-type incluye el tipo des sistema de archivos
No solo el comando df muestra el espacio restante en las particiones particulares, sino que
presenta en un cuadro leíble de dispositivos montados en cada directorio. A continuación, el
sistema de archivos en /dev/hda2 se está utilizando como partición raíz, el sistema de archivos en /
dev/hda1 está montado en el directorio /boot y /dev/hda4 está montado en /home. Una partición en
un segundo disco, es decir la partición /dev/hdb2, está montada en un directorio no estándar
denominado /data.
[elvis@station elvis]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda2 8259708 6708536 1131592 86% /
/dev/hda1 102454 24227 72937 25% /boot
/dev/hda4 5491668 348768 4863936 7% /home
/dev/hdb2 4226564 1417112 2594748 36% /data
none 127592 0 127592 0% /dev/shm
104
Medios de montaje temporal: el directorio /media.
La segunda razón por la cual los usuarios necesitan conocer los sistemas de archivos y los puntos
de montaje, involucra los medios temporales tales como los disquetes y los CD/ROM. Como
cualquier dispositivo de bloque, los disquetes y los discos CD/ROM se formatean con sistemas de
archivos. Con el fin de acceder a estos sistemas de archivos deben montarse en la estructura del
directorio, mediante un directorio (ya existente) como un punto de montaje. ¿Qué directorio debería
utilizarse?
En la última línea, el comandodf reporta ahora el controlador de disquete recién montado y elvis
puede copiar archivos en el disquete.
¿De dónde viene el directoriolost+found? Este directorio se crea al mismo tiempo que el sistema de
archivos y siempre existe en el directorio raíz de un sistema de archivos ext2 o ext3. Se usa
ocasionalmente para reparar daños en los sistemas de archivos.
105
Cuando elvis ha terminado de usar el disco, lo desmonta del sistema de archivo mediante el
comando umount.
Una vez el disco del sistema de archivos haya sido desmontado del directorio/media/floppy, el
directorio es sólo un directorio vacio.
Los dispositivos de montaje son uno de los temas mas raros y problemáticos para los nuevos
usuarios de Linux ( Unix). Los siguientes problemas se pueden presentar y agravar el asunto:
Permisos
Por defecto, solo el usuario root puede montar y desmontar dispositivos. Sin embargo, los
medios temporales se manejan de un modo diferente. El "usuario de consola" (alguien que
está conectado desde una consola virtual o una pantalla X de inicio) gana propiedades de
dispositivos asociados con la máquina física tales como un disquete y los permisos
especiales para montar estos dispositivos a los puntos de montaje predeterminados tales
como /media/floppy. Si los usuarios inician en el sistema de alguna otra manera como por
ejemplo, por red o vía el comando su, no serán considerados "usuarios de consola" y no
tendrán permiso para montar estos dispositivos.
Un sistema de archivo puede solo ser desmontado si se considera "no ocupado". ¿Qué
puede mantener a un sistema de archivo "ocupado"? Cualquier archivo abierto o cualquier
proceso que tenga un directorio actual de trabajo en el sistema de archivos, "ocupa" el
sistema de archivos. La única forma para que el sistema de archivo sea desmontado es
rastrear los procesos que puedan estar "ocupando" el sistema de archivos y matarlos.
Kernel Buffering
Con el fin de mejorar el rendimiento, el kernel memoriza todas las interacciones del
dispositivo de bloque (disco duro). Por ejemplo, cuando copia un archivo en un disquete, el
archivo puede parecer haber sido copiado casi inmediatamente.'Más tarde, al desmontar el
disquete con el comando umount, el comando se tomará un tiempo para volver mientras
se confirman la escritura en el disquete, Al desmontar el dispositivo, el kernel es forzado a
confirmar todas las transaccciones pendientes en el disco.
106
¿Qué sucedería si usted quitara el disquete del controlador antes de que la escritura
almacenada en el búfer fuera guardada en el disco? El mejor de los casos podría ser que
los archivos que creyó que tenía ya copiados en el disco no estuvieran allí. Lo peor, sería
que puede haber dañado el disco y puede que confunda al Kernel de Linux la próxima vez
se intente montar un disquete.
El resultado: no sólo debe montar medios temporales (como disquetes) antes de poder
utilizarlos, debe también desmontar los medios al terminar.
Ejemplos
La usuaria madonna tiene una colección de canciones para copiar a un disquete sin formato y
compartirlas con sus amigos. Como sabe que sus amigos usan Red Hat Enterprise Linux, decide
formatear un disquete con un sistema de archivos ext2.
107
¿Por qué no se podría desmontar el disquete? Algún proceso tiene un archivo abierto, o un
directorio de trabajo actual en el disco del sistema de archivos. El proceso infractor es la shell bash
de madonna, cuyo directorio de trabajo actual es /media/floppy . Para desmontar el disquete,
madonna debe cd a otra parte, como su directorio de inicio.
[madonna@station floppy]$ cd
[madonna@station madonna]$ umount /media/floppy/
Finalmente, madonna se encuentra con un amigo quien insiste que puede solo usar los disquetes
con formato DOS. Madonna da formato a otro disquete, esta vez con el sistema de archivo MS-
DOS, monta el disquete y copia sus archivos en él.
Después de copiar los archivos en el disquete, decide que le gustaría crear un enlace blando para
identificar la canción favorita para su amigo.
¿Por qué madonna no pudo crear el enlace? Aunque Linux soporta el sistema de archivos MS-
DOS, el sistema de archivos MS-DOS es mucho más sencillo que los sistemas de archivos
tradicionales de Linux. Linux necesita hacer algunos acuerdos. Uno de estos es que el sistema de
archivos MS-DOS no soporta enlaces blandos (ni enlaces duros). Ningún sistema de archivos
soporta los archivos propietarios y permisos de archivo. ¿Cómo maneja Linux esto? Linux trata
todos los archivos como propiedad del mismo usuario y todos los permisos como 755. ¿Qué
sucede cuando madonna trata de cambiar los permisos en uno de los archivos?
Otra vez, la operación no es permitida. Los diferentes sistemas de archivo proporcionan diferentes
capacidades y el sistema de archivos de MS DOS no es tan destacado como el sistema de
archivos ext2.
108
Ahora que ha terminado, ejecuta el comandocd a su directorio de inicio y desmonta el disquete.
Imágenes de disquete
Varios amigos le han pedido a mandonna varias copias del mismo disco. Después de un tiempo, se
cansa de formatear los disquetes, montarlos, copiar las mismas 8 canciones y desmontarlos.
Decide agilizar el proceso creando un archivo de imagen para su disquete.
[madonna@station floppy]$ cd
[madonna@station madonna]$ umount /media/floppy/
Luego, copia, el contenido del disquete desmontado, byte por byte, dentro de un archivo llamado
songs.img.
Luego, copia, el contenido del disquete desmontado, byte por byte, dentro de un archivo llamado
songs.img.
El comando cat que hemos estado usando para ver los archivos de texto sencillos, sirve tanto
como los archivos binarios o en este caso, los datos de disco binarios. Después de unos pocos
segundos de dar vueltas el disquete, ella tiene un nuevo archivo. ¿Qué tan grande es?
109
1.4 MBytes, exactamente. ¡Qué se puede esperar de un disquete! Ella almacena este archivo de
imagen desde el disquete y cada vez que alguien quiere una nueva copia de su disquete, invierte el
proceso ejecutando cat volviendo a un disco sin formato.
Dado que la imagen del archivo es transferida, byte por byte, al nuevo disquete, este comando
tiene el efecto de dar formato al disquete con un sistema de archivo ext2 y copia los archivos a
éste, todo en un solo paso. Esta es una técnica muy poderosa conocida como controladores de
imagen, y funciona en cualquier tipo de disco, no sólo en disquetes.
Cuando se accede a los dispositivos en un bajo nivel, es importante que el dispositivo sea
desmontado. Si madonna hubiera ejecutado de último en un disquete montado, el kernel muy
seguramente se habría confundido y el disquete se habría dañado.
Ejercicios en línea
Configuración
Usted necesitará un disquete para este ejercicio. El contenido del disquete será destruído.
Especificaciones
Possible Solution
110
The following sequence of commands provides one possible solution to this exercise.
Limpieza
Usted puede desmontar su disquete después de haber sido calificado, si piensa seguir al siguiente
ejercicio, grabe el contenido de su disquete.
Configuración
Necesitará el disquete creado en el ejercicio anterior, es decir, un disquete con formato ext2 que
contenga una copia recursiva del directorio /etc/sysconfig.
Especificaciones
En este ejercicio de laboratorio, usted creará un archivo imagen de un disquete y luego restaurará
el disquete mediante el archivo imagen.
111
Deliverables A title Question 1
Possible Solution
Los siguientes comandos dan una solución para los primeros cuatro pasos de este ejercicio.
Limpieza
Dado que el archivo imagen que usted creó en este ejercicio es bastante grande, puede suprimirlo
después de que el ejercicio haya sido calificado.
112
Localización de archivos con locate y find
Conceptos clave
• El comando locate utiliza una base de datos para localizar rápidamente los archivos en el
sistema por el nombre de archivo.
• El comando find realiza en tiempo real, una busqueda de modo recursivo del sistema de
archivos.
• El comando find puede buscar archivos basados en información de inodo.
• El comando find puede ejecutar comandos arbitrarios en archivos.
Discussion
Ubicación de archivos
El comando locate escribe los nombres de los archivos y directorios que coinciden con un modelo
proporcionado. Es el más rápido de los dos comandos porque éste depende de una base de datos
(actualizada a diario por defecto) en lugar de buscar en tiempo real. La desventaja de esto es que
no encontrará archivos creados hoy y encontrará archivos que hayan sido borrados desde la última
actualización de la base de datos.
El comando find puede hallar archivos por nombre, pero también puede buscar archivos por
propietario, grupo, tipo, fecha de modificación y otros criterios. Con su búsqueda en tiempo real a
través del árbol de directorio es más lento que con locate, pero también es más flexible.
Uso de Locate
Anteriormente, usamos el comando umount para desenlazar un sistema de archivo desde un árbol
de directorios. Veamos qué archivos en el sistema de archivos incluyen la cadena "umount" en sus
nombres.
113
Observe que además de /bin/umount también hemos localizado el comando smbumount y varios
archivos de páginas del manual.
Uso de find
El comando find se utiliza para buscar en el sistema de archivos archivos que cumplan con el
criterio especificado. Casi cualquier aspecto del archivo se puede especificar como por ejemplo, el
nombre, el tamaño, la última modificación, e incluso el conteo de enlaces (la única excepción es el
contenido del archivo. Para el cual debemos esperar por un comando llamado grep, el cual se
complementa muy bien con find).
Toma un poco de tiempo familiarizarse con la sintaxis del comando find, pero una vez aprendida
es muy útil. Un comando find consta por naturaleza de tres partes: un directorio raíz (o directorios),
criterios de búsqueda y una acción.
El directorio predeterminado es ".", los criterios por defecto son "todo archivo", y la acción por
defecto es "imprimir" (el nombre de archivo), por lo tanto al ejecutar el comando find sin
argumentos simplemente bajará el directorio actual, e imprimirá cada nombre de archivo. Si se
diera un directorio como único argumento, lo mismo se haría para ese directorio.
114
[madonna@station madonna]$ find /etc/sysconfig/networking/
/etc/sysconfig/networking/
/etc/sysconfig/networking/devices
/etc/sysconfig/networking/devices/ifcfg-eth0
/etc/sysconfig/networking/profiles
/etc/sysconfig/networking/profiles/default
/etc/sysconfig/networking/profiles/default/network
/etc/sysconfig/networking/profiles/default/resolv.conf
/etc/sysconfig/networking/profiles/default/hosts
/etc/sysconfig/networking/profiles/default/ifcfg-eth0
/etc/sysconfig/networking/profiles/netup
/etc/sysconfig/networking/profiles/netup/network
/etc/sysconfig/networking/profiles/netup/resolv.conf
/etc/sysconfig/networking/profiles/netup/hosts
/etc/sysconfig/networking/profiles/netup/ifcfg-eth0
/etc/sysconfig/networking/ifcfg-lo
No obstante, por lo general el comando find se le da criterios para refinar su búsqueda, en forma
de opciones (no estándar). Por ejemplo, la opción -name se utiliza para buscar archivos con un
nombre dado (o nombre comodín).
Aunque superficialmente similar a las funciones de los comandos locate, el comando find funciona
realizando una búsqueda en tiempo real. Esto puede tardar mucho más, pero evita el problema de
una base de datos "fuera de sincronización" Tenga en cuenta que si no se sigue el orden correcto,
el comando find se torna confuso rápidamente.
Busque criterios
Si usted navega la página find(1) del manual, descubrirá que se pueden especificar una cantidad
abrumadora de criterios para su búsqueda. Casi cualquier aspecto del archivo que el comando stat
o el comando ls puedan reportar es parte del juego limpio. El siguiente cuadro resume algunos de
los criterios de búsqueda más comunes.
115
opción especificaciones
-empty El archivo es un directorio o un archivo regular y está vacío.
-group El archivo pertenece al grupo gname.
gname
-inum n El archivo tiene un número de inodo n.
-links n El archivo tiene n enlaces.
-mmin n El archivo fue modificado hace n minutos.
-mtime n El archivo fue modificado hace n días.
-nombre El nombre del archivo coincide con el archivo comodín patrón.
patrón
-newer El archivo fue modificado más recientemente que filename.
filename
-permmode Los permisos del archivo son exactamente mode.
-perm -mode Todos los bits de permisos mode se establecen para el archivo.
-perm Cualquiera de los bits de permiso modese establecen para el archivo.
+mode
-size n El archivo tiene un tamaño de n.
-type c El archivo es de tipo c, en donde c es "f" (archivo regular), "d" (directorio), o "l"
(enlace simbólico). Vea la página del manual para encontrar mayor información.
-user uname El archivo es de propiedad del usuario uname.
Hay más opciones disponibles, pero con estas se puede dar una idea de la flexibilidad del
comando find. Cualquier criterio que tome un argumento numérico tal como -size o -mtime,
reconoce los argumentos de la forma +3 (lo que significa mayor que 3), -3 (significa menor que 3),
ó 3 (significa exactamente 3).
Si hay múltiples criterios especificados, por defecto, todos los criterios deben cumplirse. No
obstante, si los múltiples criterios son separados por -or, cualquier condición puede cumplirse. Los
criterios pueden ser invertidos por los criterios anteriores con -not.
A manera de ejemplo, el siquiente comando busca todos los archivos bajo /var, los cuales no
tienen permiso de escritura para el grupo.
Buscar acciones
Usted puede también especificar qué le gustaría hacer a los archivos que cumplen con los criterios
especificados, el nombre del archivo imprime en salida estándar, un archivo por línea. Las demás
opciones se resumen en el siguiente cuadro.
116
Opción Acción
-exec Ejecuta commanden archivos coincidentes. Usa {}para indicar dónde debe
command ; sustituirse el nombre de archivo.
-ok command ; Igual que -exec, pero prompt para cada archivo
-ls Imprime archivo en formato ls -dils.
Quizás, el comando más útil y sin duda más extraño de estos es -exec, y su primo cercano -ok. El
mecanismo de -exec es un mecanismo poderoso: en lugar de imprimir los nombres de los archivos
coincidentes, ejecuta los comandos arbitrarios. El mecanismo del comando -exec es extraño
porque la sintaxis para especificar el comando es complicada. El comando debería escribirse
después de la opción-exec, utilizando un {} literal como parámetro para el nombre de archivo. El
comando debería terminarse con un ; literal, pero como veremos en un cuaderno más adelante, el ;
tiene un significado especial para la shell y por lo tanto se debe "escapar" agregándole un \.
Veamos el siguiente ejemplo.
Suponga que madonna quería una copia de cada archivo mayor de 200 bytes del directorio /etc.
Primero, busca los archivos que cumplen con los criterios.
(El comando 2>/dev/null sirve para "botar " las quejas acerca de los directorios a los que madonna
no tiene permisos de acceso).
Para confirmar los tamaños de los archivos, ella vuelve a ejecutar el comando, especificando la
"acción" de -ls.
Ahora, ella crea un directorio llamado /tmp/big y compone un comando cp en la línea de comando
find, recordando lo siguiente.
117
• Termine el comando con un \;.
En lugar de imprimir el nombre del archivo, el comando find copió los archivos en el directorio /tmp/
big.
Ejemplos
Uso de locate
En los ejemplos anteriores, locate muestra todo en la base de datos con la cadena
"rmdir"incluyendo el comando y las páginas del manual. El comando find muestra todos los
archivos bajo el /bin que incluyen "dir" en el nombre. Por último, el comando which muestra la ruta
absoluta para un comando conocido.
Usted también puede incluir los caracteres de expansión del nombre de archivo en su búsqueda:
118
Recuerde que el comando locate usa una base de datos y no localizará archivos que hayan sido
creados desde la última modificación de la base de datos. El ejemplo anterior no debería mostrar
ninguna salida de dicho comando.
Uso de find
El comando find busca el árbol de directorios real desde el punto de inicio especificado.
El comando find listará todos los archivos incluyendo todos los archivos ocultos cuando sólo se
especifica un directorio de inicio. Sin embargo, cuando se está buscando el nombre de archivo, es
importante especificar si se van a buscar archivos ocultos.
119
[elvis@station elvis]$ find /bin /usr/bin -name "*dir*"
/bin/mkdir
/bin/rmdir
/usr/bin/dir
/usr/bin/dircolors
/usr/bin/vdir
/usr/bin/dirname
/usr/bin/mdir
/usr/bin/ttmkfdir
/usr/bin/directomatic
/usr/bin/pi-nredir
Genera con ls -l un listado de estilos de todo lo que no sea propiedad en el sistema de los usuarios
root, bin o student. Pueden haber directorios donde el acceso de búsqueda sea negado por lo
tanto, también redirige los errores a /dev/null para que no aparezcan en la pantalla.
[elvis@station elvis]$ find / -not -user root -not -user bin -not -user student
-ls 2> /dev/null
...
8037 1 drwxr-xr-x 2 ntp ntp 1024 Dec 22 17:08 /etc/ntp
8040 0 -rw-r--r-- 1 ntp ntp 0 Aug 31 2002
/etc/ntp/step
-tickers
8038 1 -rw-r--r-- 1 ntp ntp 4 Aug 31 2002
/etc/ntp/drif
t
8039 1 -rw------- 1 ntp ntp 266 Aug 31 2002
/etc/ntp/keys
42299 8 -rw-r----- 1 smmsp root 12288 Mar 4 08:17
/etc/mail/vir
tusertable.db
42300 12 -rw-r----- 1 smmsp root 12288 Mar 4 08:17
/etc/mail/acc
ess.db
42301 8 -rw-r----- 1 smmsp root 12288 Mar 4 08:18
/etc/mail/dom
aintable.db
42302 8 -rw-r----- 1 smmsp root 12288 Mar 4 08:18
/etc/mail/mai
lertable.db
28204 12 -rw-r----- 1 smmsp smmsp 12288 Mar 16 15:36
/etc/aliases.
db
44276 2044 -rwxr-xr-x 1 rpm rpm 2083816 Sep 4 2002 /bin/rpm
120
Uso de find para ejecutar comandos en archivos
Busca todos los archivos que están bajo /tmp con el conteo de enlace mayor que 1 y hace una
copia de cada uno en un directorio llamado /tmp/links.
Ejercicios en línea
Ubicación de archivos Lab Exercise Objetivo: Diseñar y ejecutar un comando find que genere el
resultado descrito en cada uno de los siguientes.Tiempo estimado: 20 minutos.
Especificaciones
Use el comando find para buscar archivos coincidentes con los siguientes criterios y redireccione
la salida a los archivos especificados en su directorio de inicio. Al listar los archivos asegúrese de
que cada nombre de archivo sea una referencia absoluta.
Puede que necesite consultar la página del manual find(1) para hallar respuesta a algunos de los
problemas.
content_view let_
Deliverables A title Question 1
1. El archivo varlib.games contiene un listado de todos los archivos bajo el directorio /var/lib,
pertenecientes al usuario "games".
2. El archivo var.rootmail contiene un listado de todos los archivos bajo el directorio /var,
pertenecientes al usuario "root" y al grupo "mail".
3. El archivo bin.big contiene un listado de estilos ls -dils de todos los archivos bajo el
directorio /usr/bin mayores de 1000000 caracteres de tamaño.
4. Ejecute el comando file en cada archivo bajo /etc/sysconfig y registre la salida en el archivo
sysconfig.find.
121
5. El archivo big.links contiene un listado de nombres de archivos regulares bajo el directorio /
usr/lib/locale, el cual tiene un conteo de enlaces mayor a 100.
122
Comprimir archivos: gzip y bzip2
Conceptos clave
Discussion
Los archivos que no se utilizan mucho con frecuencia se comprimen. Los archivos grandes también
se comprimen antes de transferirlos a otros sistemas o usuarios. Las ventajas del ahorro de
espacio y de amplitud de banda suelen superar el tiempo que toma para comprimir o descomprimir
archivos.
Los archivos de texto a menudo tienen patrones que se pueden comprimir hasta un 75% , pero los
archivos binarios rara vez comprimen más de un 25%. De hecho, es incluso posible que un archivo
binario sea ¡más grande que el original!
Dado que se han desarrollado cada vez mejores técnicas de compresión, se han ganado nuevas
utilidades de compresión. Sin embargo, para compatibilidad retroactiva las utilidades de
compresión aún se retienen. A menudo, se compensa entre la eficiencia de compresión y la
actividad de CPU. Algunas veces, utilidades más antiguas son "suficientemente "buenas para
hacer el trabajo en mucho menos tiempo.
La siguiente lista presenta las dos utilidades para comprimir más comunes que se utilizan en Linux
y Unix.
gzip (.gz)
El comando gzip es la utilidad de descompresión más versátil y la que más se utiliza. Los
archivos comprimidos con gzip se descomprimen con gunzip. Además, el comando gzip
soporta las siguientes opciones.
Opción Efecto
-c Redireccionar la salida a stdout
-d Descomprimir en lugar de comprimir el archivo
-r Ir de modo recursivo a través de subdirectorios, comprimiendo archivos individuales.
-1 ... -9 Especificar la compensación entre la intensidad del CPU y la eficiencia de la
comprensión.
bzip2 (.bz)
El comando bzip2 es un recién llegado que tiende a generar los archivos comprimidos más
compactos, pero utiliza la CPU de manera más intensiva. Los archivos comprimidos con
bzip2 se descomprimen con bunzip2. El comando bzip2 soporta las siguientes opciones.
123
Opción Efecto
-c Redireccionar la salida a stdout
-d Descomprimir en lugar de comprimir el archivo
Los ejemplos a continuación ilustran el uso y la eficiencia relativa de los comandos de compresión.
Otra utilidad de compresión disponible en Red Hat Enterprise Linux es zip. Esta utilidad es
compatible con las utilidades de DOS/Windows PKzip/Winzip y pueden comprimir más de un
archivo en un archivo único, algo que los comandos gzip y bzip2 no pueden hacer.
Los usuarios de Linux y Unix prefieren usar los comandos tar ygzip juntos en lugar de zip. El
comando tar se describe en la siguiente lección.
Ejercicios en línea
Trabajar con las utilidades de compresión Lab Exercise Objetivo: Comprimir archivos
grandesEstimated Time: 10 mins.
Especificaciones
124
Deliverables A title Question 1
content_view let_
125
Archivar ficheros con tar
Conceptos clave
Discussion
Archivadores de ficheros
Con frecuencia, si un directorio y sus archivos subyacentes no se van a utilizar por un tiempo, o si
el árbol entero de directorios se transfiere de un lugar a otro, la gente convierte al árbol de
directorios en un archivador. El archivo contiene el directorio y sus archivos y subdirectorios
subyacentes, empacados como un solo archivo. En Linux (y Unix), el comando más común para
crear y extraer archivos es el comando tar.
En un inicio, los archivadores de ficheros fueron una solución para hacer una copia de seguridad
de discos en cintas magnéticas. Al hacer una copia de seguridad de un sistema de archivos, la
estructura entera de directorio se convertía en un solo archivo, el cual se escribía directamente al
controlador de cinta. El comando tar se deriva del inglés "t"ape "ar"chive.
Actualmente, el comando tar se utiliza muy rara vez para escribir directamente en las cintas, pero
en su lugar crea archivadores de ficheros que a menudo se denominan "ficheros tar", "archivos
tar", o algunas veces de un modo informal como "tarballs". A estos paquetes de archivos suele
dárseles la extensión del nombre de archivo .tar.
Cuando se ejecuta el comandotar, se debe seleccionar la primera línea del comando de las
siguientes opciones.
Opción Efecto
-c, --create Crear un archivador de ficheros
-x, --extract Extraer un archivador de ficheros
-t, --list Lista el contenido de un archivador de ficheros
Hay otros, pero casi siempre uno de estos tres será suficiente. Para mayor información consulte la
página del manual tar(1).
Casi cada invocación del comando tar debe incluir la opción -f y su argumento, el cual especifica el
archivador de ficheros que se está creando, extrayendo o listando.
A manera de ejemplo, el usuario prince ha estado trabajando en un informe, el cual involucra varios
archivos y subdirectorios.
126
report/
|-- html/
| |-- chap1.html
| |-- chap2.html
| `-- figures/
| `-- image1.png
`-- text/
|-- chap1.txt
`-- chap2.txt
3 directories, 5 files
Le gustaría enviar por correo-e una copia del informe a un amigo. En lugar de adjuntar cada
archivo de manera individual a un correo-e decide crear un archivador del directorio del informe.
Utiliza el comando tar, especificando -c para "c"rear un archivo y utilizar la opción -f para
especificar el archivador de ficheros que va a crear.
El archivador de ficheros recién creado report.tar, contiene ahora todo el contenido del directorio
report y sus subdirectorios. Con el fin de confirmar que el archivo fue creado correctamente, prince
lista el contenido del archivador del fichero con el comando tar -t (utilizando una vez más -f para
especificar el archivador de fichero).
Para confirmar una vez más, prince extrae el archivador de ficheros en el directorio /tmp mediante
el comando tar -x.
127
[prince@station prince]$ cd /tmp
[prince@station tmp]$ tar -x -f /home/prince/report.tar
[prince@station tmp]$ ls -R report/
report/:
html text
report/html:
chap1.html chap2.html figures
report/html/figures:
image1.png
report/text:
chap1.txt chap2.txt
Convencido de que el archivador de ficheros contiene el informe y que su amigo podrá extraerlo,
limpia la copia de prueba y utiliza el comando mutt para enviar por correo-e el archivador a manera
de anexo.
No se preocupe si no está familiarizado con el comando mutt. Sólo sirve de ejemplo del porqué
alguien podría querer crear un archivador tar.
La primera opción de tar debe ser una de las opciones especiales descritas anteriormente. Puesto
que la primera es siempre una de las pocas opciones, el comando tar permite un atajo, usted no
necesita incluir el guión inicial. Con frecuencia, los usuarios con experiencia en ejecutar tar utilizan
el modo abreviado de la línea de comando de la siguiente manera.
Crear archivos presenta una serie de preguntas complicadas tales como las siguientes.
• ¿Cuando se crean archivos, cómo se deberían manejar los enlaces? ¿Debo archivar el
enlace? o ¿a qué se refiere el enlace?
128
• Cuando extraemos los archivos como root, ¿quiero que todos los archivos pertenezcan a
root o al propietario original? ¿Qué sucede si el propietario original no existe en el sistema
en el que estoy desempacando el tar?
• ¿Qué sucede si el controlador de cinta magnética en el que estoy archivando no tiene más
espacio cuando voy en la mitad del archivo?
Las respuestas a estas y otras preguntas se pueden resolver con un abrumador número de
opciones para el tar como tar --help o una mirada rápida a la página del manual tar(1) se lo
mostrará. El siguiente cuadro lista algunos de las opciones que se utilizan con más frecuencia a
continuación explicaremos su uso.
Opción Efecto
-C, --directory=DIR Cambia al directorio DIR
-P, --absolute-reference sin / inicial desde los nombres de archivos
-v, --verbose Lista los archivos procesados
-z, --gzip internamente gzip el archivo
-j, --bzip2 internamente bzip2 el archivo
Referencias absolutas
Suponga que prince desea archivar una instantánea de la configuración de la red de trabajo actual
de su máquina. Podría ejecutar un comando como el siguiente (observe la inclusión de la opción -v
que lista cada archivo a medida que se procesa).
129
[prince@station prince]$ tar xvf net.tar
etc/sysconfig/networking/
etc/sysconfig/networking/devices/
etc/sysconfig/networking/devices/ifcfg-eth0
etc/sysconfig/networking/profiles/
etc/sysconfig/networking/profiles/default/
etc/sysconfig/networking/profiles/default/network
etc/sysconfig/networking/profiles/default/resolv.conf
...
[prince@station prince]$ ls -R etc/
etc/:
sysconfig
etc/sysconfig:
networking
etc/sysconfig/networking:
devices ifcfg-lo profiles
etc/sysconfig/networking/devices:
ifcfg-eth0
etc/sysconfig/networking/profiles:
default netup
etc/sysconfig/networking/profiles/default:
hosts ifcfg-eth0 network resolv.conf
etc/sysconfig/networking/profiles/netup:
hosts ifcfg-eth0 network resolv.conf
Dado que las entradas al fichero fueron relativas, el archivador fue desempacado en el directorio
local. Como regla, los archivadores de ficheros siempre desempacarán de modo local, reduciendo
la posibilidad de sobrescribir ficheros en el sistema al desempacar un archivo en ellos. Al construir
el archivo, esta conducta se puede anular con la opción -P.
Establecer el contexto
130
[prince@station prince]$ tar cvf net.tar /etc/sysconfig/networking
tar: Removing leading `/' from member names
etc/sysconfig/networking/
etc/sysconfig/networking/devices/
etc/sysconfig/networking/devices/ifcfg-eth0
etc/sysconfig/networking/profiles/
etc/sysconfig/networking/profiles/default/
etc/sysconfig/networking/profiles/default/network
...
[prince@station prince]$ tar cvf net.tar -C /etc/sysconfig networking
networking/
networking/devices/
networking/devices/ifcfg-eth0
networking/profiles/
networking/profiles/default/
networking/profiles/default/network
...
Dado que las entradas al fichero fueron relativas, el archivador fue desempacado en el directorio
local. Como regla, los archivadores de ficheros siempre desempacarán de modo local, reduciendo
la posibilidad de sobrescribir ficheros en el sistema al desempacar un archivo en ellos. Al construir
el archivo, esta conducta se puede anular con la opción -P.
Establecer el contexto
Dado que los usuarios están a menudo creando y comprimiendo archivos o trantando con archivos
que han sido comprimidos, el comando tar proporciona tres opciones para comprimir internamente
(o descomprimir) archivadores de ficheros. Arriba, prince pudo haber obtenido el mismo resultado
al agregar la opción -z.
131
La combinación de los comandos tar y gzip se encuentra tan a menudo, que la extensión
de.tar.gzsuele abreviarse como .tgz.
Como el archivo estaba comprimido, debe descomprimirse (ya sea con la opción o con el comando
de descompresión apropiados) antes de que el archivo pueda ser extraído o examinado. Es
importante etiquetar los archivos con las extensiones de nombre de archivo apropiadas para que
cualquiera sepa cómo desempacarlo.
Ejemplos
El usuario einstein desea hacer una copia de la documentación de bash para poder llevarla
consigo. Pronto ejecuta tar en el directorio/usr/share/doc/bash-2.05b.
132
[einstein@station einstein]$ tar xvzf bashdoc.tgz
bash-2.05b/
bash-2.05b/article.ms
bash-2.05b/CHANGES
bash-2.05b/COMPAT
bash-2.05b/FAQ
bash-2.05b/INTRO
...
El usuario maxwell desea comparar rápidamente la configuración LDAP en dos equipos diferentes.
Las máquinas no están conectadas a la red, pero ambas tienen un disquete. En lugar de crear un
archivo, formateando un disquete, montando un disquete, copiando el archivo y desmontando el
disquete, maxwelll decide ahorrarse unos cuantos pasos. Con un disquete desmontado en el
controlador, ejecuta el siguiente comando.
Aunque el comando tar (o más exactamente, el comando gzip) se quejó de la "basura de rastreo",
el archivo se extrajo con éxito.
¿Qué sucedió aquí? El comando tar escribió directamente al nodo de dispositivo del disquete, para
que el archivador de fichero fuera escrito byte por byte al disquete como datos crudos. Al extraer el
archivador, el archivo completo se lee byte por byte. Sin embargo, el comando gzip sigue
ejecutándose, tratando de descomprimir lo que estaba en el disquete antes de que se escribiera el
archivo. Esta es la "basura de rastreo" de la que el comando gzip se quejó. ¿Cuál era el nombre
de archivo del archivador cuando estaba en el disquete? -¡Pregunta delicada!
¡Ay!
133
El usuario einstein quiere crear un archivo de su directorio de inicio. Ensaya el siguiente comando.
¿Por qué el comando tar mostró un error? El archivador estaba siendo escrito en el fichero /home/
einstein/einstein.tgz. El archivador incluyó cada fichero en el directorio /home/einstein. Por último,
el comando tar trató de adjuntar el fichero /home/einstein/einstein.tgz al archivador /home/einstein/
einstein.tgz. Esto obviamente causa problemas.
¿Qué solución? Asegúrese que el archivador de ficheros que está creando no existe en el
directorio que usted está archivando. El directorio /tmp es muy útil.
Ejercicios en línea
Archivar directorios Lab Exercise Objetivo: Crear un archivo con el comando tar.Tiempo
estimado: 15 minutos.
Especificaciones
134
Creación de un archivo crudo en un disquete Lab Exercise Objetivo: Crear un archivo
directamente en un disquete.Tiempo estimado: 5 minutos.
Configuración
Especificaciones
1. Un disquete que contiene un archivo crudo comprimido con gzip del directorio
/usr/share/doc/gzip*, en donde el directorio se especificó como una referencia absoluta.
Possible Solution
135
The Bash Shell
Introducción a Bash
Conceptos clave
Discussion
La shell bash
En Linux, la shell es el programa más utilizado. La shell es lo que usted ve cuando inicia sesión o
cuando abre una terminal y lo que más usa para iniciar cada comando. Aunque hay una variedad
de shells disponibles, todas siguen la misma conducta básica: escuchar los comandos del usuario,
iniciar procesos como se especifica en los comandos e informar los resultados al usuario. La shell
más utilizada en Linux es la shell bash, la cual es la shell por defecto en Red Hat Enterprise Linux.
La shell bash no sólo es de fácil uso para tareas sencillas, sino también tiene capacidades de gran
alcance para facilitar tareas complejas o incluso hacerlas posibles. Esta eficacia trae consigo
complejidad, solo basta con dar un vistazo a la página bash del manual (que tiene mas de 4.500
líneas) para convencerse. Este cuaderno presentará muchas de estas capacidades de gran
alcance.
La shell bash está diseñada para ser eficaz para dos tipos diferentes de uso. Usted ya está
familiarizado con el uso del comando bash como una shell interactiva. Muchas de estas
características de bash permiten a las personas escribir comandos de una manera más fácil y
eficaz y gran parte de este cuaderno se enfocará en estas habilidades.
La shell bash también está diseñada para ser un lenguaje de escritura de gran alcance. Los scripts
de la shell bash son programas pequeños escritos mediante la misma sintaxis que se utiliza en la
línea de comandos. Los scripts de shell permiten a los usuarios automatizar las acciones repetidas
al combinar una serie de comandos. A diferencia de las shells interactivas, los scripts de shell
suelen ejecutar una serie de comandos de modo no interactivo y muchas de estas características
de la shell bash proveen una programación lógica (tales como ramas y bucles) para escribir scripts
sofisticados. Al final de este cuaderno encontrará una introducción a la escritura de shell.
Al continuar a través de este cuaderno, trate de tener en la mente estos dos usos diferentes de la
shell bash. Algunas características de bash, tales como el historial de comandos, que pronto
veremos, son casi inútiles en los scripts de shell. Otros rasgos, tales como la sustitución aritmética,
pueden no parecer út¡les en la línea de comandos, pero pueden ser útiles en un script de shell. Si
136
la utilidad de una característica de un bash no es de inmediato obvia, trate de verla en otro
contexto.
Shells de inicio
En la práctica, los usuarios a veces necesitan iniciar una shell de modo manual. Cada vez que
alguien inicie sesión o abra una terminal, una shell se inicia automáticamente. Sin embargo, a
veces los usuarios desearían ejecutar una shell diferente u otra instancia de la misma shell. Dado
que la shell es sólo "otro programa", nuevas shells pueden iniciarse desde la shell existente. La
nueva shell se denomina subshell de la shell original. Cuando se sale de la subshell, el control
vuelve a la shell original. En el siguiente ejemplo, madonna inicia una subshell bash, lista los
procesos desde dentro de ésta para confirmar que las dos shells se están ejecutando y luego sale
de la subshell.
Cuando inicia una subshell bash, las diferencias aparentes entre la subshell y la shell padre son
mínimas y se debe tener cuidado de seguir el rastro de la shell en la que se encuentra.
El archivo ~/.bashrc
Como parte de su inicialización, la shell bash buscará en el directorio de inicio del usuario un
archivo titulado .bashrc. El archivo se emplea para personalizar la shell bash. Cuando la shell
inicia, los comandos listados en el archivo se ejecutan como si fueran escritos en la línea de
comandos. Técnicamente, la shell bash "lee" el archivo. Los conceptos relacionados con la lectura
de archivos y la inicialización de shell se tratarán en detalle más adelante. Aquí, presentaremos
rápidamente este sólo archivo para poder hacer uso de él en ejercicios posteriores.
A continuación, madonna edita su archivo ~/.bashrc agregándole el comando cal, para que tras el
arranque la shell bash se presente un calendario del mes actual.
137
[madonna@station madonna]$ nano .bashrc
... (madonna appends a single line containing the command "cal") ...
cal
La usuaria madonna agregó esta única línea. Las líneas restantes se encuentran en un
archivo por defecto ~/.bashrc de un usuario.
Ahora, cada vez que madonna inicia una shell bash (por ejemplo, iniciando en una consola virtual
o abriendo otra ventana de terminal), se presenta un calendario.
Introducir Comandos
Las shells interactivas repiten el ciclo de escuchar una línea de comandos, evalúan el comando
solicitado, realizan todas las acciones solicitadas y muestran los resultados. La shell escucha al
teclado de entrada y emplea la tecla de ENTER para reconocer el final de la entrada como en la
siguiente ejecución del comando echo.
Historial de comandos
Como conveniencia para los usuarios de shells interactivas, el comando shell bash mantiene el
historial de cada uno de los comandos escritos por el usuario y ofrece una variedad de formas para
hacer que los comandos desde este historial estén a su alcance. La forma más fácil de ver el
historial actual es mediante el comandohistory.
138
[blondie@station blondie]$ history
1 ls -l /home/
2 ls -ln /home/
3 exit
4 exit
5 id
...
167 mv rhyme stuff/
168 ls -Rli
169 exit
170
171 exit
172 history
Como se muestra, el comando history entrega un historial de los comandos previamente escritos,
con cada entrada precedida por un "número de historial". El comando history va hasta el final de la
lista. Desde la línea de comandos, las teclas de dirección ARRIBA y ABAJO atraviesan pronto la
lista de arriba a abajo, mientras que las teclas de dirección IZQUIERDA y DERECHA moverán el
cursor para permitir al usuario editar un comando dado. Por ejemplo, si blondie quisiera luego
ejecutar el comando ls -li, podría pulsar la tecla ARRIBA 5 veces y su intérprete de comandos
llenaría con el comando ls -Rli. Podría entonces pulsar dos veces la tecla de dirección IZQUIERDA
y RETROCESO para suprimir R de la línea de comandos seguido por la tecla ENTER. Mediante
las teclas de flecha, los usuarios pueden rápidamente revisar, editar y ejecutar comandos
tecleados anteriormente.
Sustitución de historial
Como una alternativa a las teclas de dirección, la shell bash también realiza "sustitución de
historial", la cual se desencadena por el signo de exclamación. El siguiente cuadro resume la
sintaxis de sustitución de historial más utilizada.
Sintaxis Sustitución
!! Comando anterior
!n Comando número n
!-n El comando más reciente n
!cmd El comando más reciente que comienza por cmd
A manera de ejemplo de la sintaxis anterior, analice la siguiente salida (abreviada) cuando blondie
ejecuta el comando history.
139
[blondie@station blondie]$ history
...
161 ls
162 ls -il
163 ln rhyme hard_link
164 ls -il
165 chmod 660 rhyme
166 ls -il
167 mv rhyme stuff/
168 ls -Rli
169 exit
170
171 exit
172 history
El siguiente cuadro lista lo que blondie escribiría en la línea de comandos y el comando resultante
que ejecutaría.
No sólo el comando shell bash mantiene un historial de comandos dentro de una sesión, sino que
también conserva los historiales de comandos entre sesiones. Cuando la shell bash sale, entrega
el historial actual del comando dentro de un archivo llamado .bash_history en un directorio de inicio
del usuario. Tras el arranque, la shell inicializa el historial de comandos desde el contenido de este
archivo.
¿Qué repercusión tienen estas shells interactivas múltiples (pertenecientes a un mismo usuario) al
ejecutar al mismo tiempo? Puesto que el historial solo se ha guardado en el disco cuando la shell
sale, los comandos ejecutados en un proceso bash no están disponibles en el historial de
comandos de un procesobash ejecutado simultáneamente. Además, la última shell al salir
sobrescribirá las historias de las shells que salieron anteriormente.
Si está establecido así, las siguientes variables configuran los detalles de cómo se guarda el
historial de comandos.
140
Trucos del historial de comandos
La shell bash ofrece muy pocas técnicas para acceder previamente los comandos tecleados (o
elementos del mismo).
ESC-. y ALT-.
CTRL-R
Esta secuencia clave imita a !cmd en espíritu. El texto tecleado después de CTRL-R
coincide con los comandos tecleados anteriormente con la ventaja de que las líneas de
comandos coincidentes se ven de modo inmediato al teclear el texto. Usted también tiene
la oportunidad de editar la línea recuperada (utilizando las teclas de dirección IZQUIERDA
y DERECHA u otros golpes de teclado de edición de líneas de comando) antes de ejecutar
el comando.
fc
Ejemplos
Con frecuencia, los programadores de lenguajes compilados tales como C suelen hallarse en un
ciclo repetitivo: editar un archivo, compilarlo y luego ejecutar el programa. A continuación, madonna
edita un archivo que contiene un programa pequeño C y luego lo compila con el compilador C gcc.
Después de ejecutar el programa, decide hacer algunos cambios. Hace entonces uso del historial
de comandos para agilizar el proceso.
141
[madonna@station madonna]$ nano hello.c
[madonna@station madonna]$ cat hello.c
#include "stdio.h"
int main(void)
{
printf("hello world\n");
return 0;
}
[madonna@station madonna]$ gcc -o hello hello.c
[madonna@station madonna]$ ./hello
hello world
[madonna@station madonna]$ !n
nano hello.c
(... madonna edits the file, replacing the string "hello world"
with "hello dolly" ...)
[madonna@station madonna]$ !c
cat hello.c
#include "stdio.h"
int main(void)
{
printf("hello dolly\n");
return 0;
}
[madonna@station madonna]$ !g
gcc -o hello hello.c
[madonna@station madonna]$ !.
./hello
hello dolly
Observe que la shell bash imprime el comando seleccionado desde el historial de madonna antes
de ejecutar el comando.
Uso de ESC.
Ahora madonna quisiera crear un subdirectorio bin, establece sus permisos para que sólo ella
pueda acceder a éste y mover su archivo ejecutable hello en él. Usa la secuencia de teclas ESC-.
para agilizar el proceso.
Quizas no es el ejemplo más interesante porque bin es un directorio muy pequeño para teclear de
todas maneras. Sin embargo, si hubiera sido el directorio /usr/lib/perl5/ven or_perl/5.8.0/HTML/, los
golpes de teclado grabados serían impresionantes.
142
Inhibición del historial de comandos
Madonna ahora puede usar el historial de comandos de bash para recuperar los comandos
utilizados en la shell actual, pero ningún historial de comandos se almacenará entre las instancias
de shell.
Ejercicios en línea Lab Exercise Objetivo: Personalizar su archivo ~/.bashrc para mantener un
registro de cuándo se inician las shells.Estimated Time: 10 mins.
Especificaciones
1. Use un editor de texto para modificar el archivo .bashrc desde su directorio de inicio,
agregando la siguiente línea al final del archivo.
El archivo .bashrc debe también contener una línea de comentario que incluya su nombre de
usuario.
143
Listas de comandos y scripts
Conceptos clave
Discussion
La shell bash permite a los usuarios unir comandos múltiples en una sola línea de comandos
separando los comandos con un ;. (en inglés es igual; las frases independientes se separan con un
punto y coma). Veamos un ejemplo:
La única diferencia entre los dos enfoques es que no se tiene la oportunidad de examinar el efecto
del primer comando antes de que el segundo comando se ejecute. Muy pocas veces existe la
necesidad real de ejecutar comandos múltiples desde una solo línea de comandos, pero suele ser
conveniente combinar los comandos.
La shell bash permite a los usuarios la fácil ejecución de comandos en una subshell, delimitando el
comando entre paréntesis. Considere el siguiente ejemplo:
144
[elvis@station elvis]$ (cd /etc/X11; ls)
applnk prefdm sysconfig xorg.conf.backup xkb
desktop-menus proxymngr twm xorg.conf.wbx Xmodmap
fs rstart X xorg.conf.works Xresources
gdm serverconfig xdm XftConfig.README-OBSOLETE xserver
lbxproxy starthere xorg.conf xinit xsm
[elvis@station elvis]$
A primera vista, la conducta parece idéntica a la del ejemplo anterior. Una mirada más de cerca
revela una diferencia sutil pero importante. En el primer ejemplo, cuando los comandos se separan
apenas por un punto y coma, los comandos se ejecutan en la shell actual. El intérprete de
comandos de bash revela que, después de ejecutados los comandos, la shell del directorio de
trabajo actual ha cambiado a /etc/X11 como resultado del comando cd.
En el ejemplo anterior, al delimitar los comandos entre paréntesis, el directorio de shell actual no
cambia. Cuando bash encuentra un paréntesis en la línea de comandos, éste genera un nuevo
proceso hijobash (llamado subshell) y ejecuta los comandos dentro de la subshell. Después de
ejecutarlos, la subshell sale y el usuario queda en la shell original (shell sin cambios). El efecto es
parecido a la siguiente secuencia de comandos.
Ahora que elvis está de nuevo en su shell original, las modificaciones en la subshell (tales
como el cambio en el directorio de trabajo actual) han quedado atrás.
¿Por qué podría alguien desear ejecutar un comando en una subshell? Las subshells se utilizan
para evitar efectos secundarios. Lo que suceda en la subshell no debería tener efecto en el entorno
original de la shell (como en inglés, lo que está entre paréntesis no debe cambiar la frase que lo
rodea).
La clave para usar Red Hat Enterprise Linux de modo efectivo es la automatización. Un buen
administrador de Linux debe ser en realidad extremadamente perezoso cuando se trata de hacer
algo aburridor o repetitivo. Las secciones anteriores ilustraron la manera de encadenar comandos
para ejecutar de modo consecutivo o simultáneo en lugar de esperar a que el comando termine
145
antes de teclear el próximo. También le introdujeron a las características del historial de bash y le
mostraron cómo referirse a comandos tecleados previamente para que sólo tenga que escribirlos
una vez.
Sin embargo, aún falta una parte importante de la caja de herramientas del administrador del
sistema: la escritura de scripts. Un script, en su forma más simple, es un texto con una lista de
comandos en él. Los comandos se envían a través de un programa específico llamado intérprete,
el cual ejecuta un comando a la vez. Este intérprete suele ser la shell bash (conocida como
/bin/bash o /bin/sh) y cada comando es un comando común de Linux. Otros intérpretes permiten
utilizar lenguajes de programación de gran alcance como Perl, Python y Ruby.
Antes de comenzar a escribir sus propios scripts hay algunas cosas importantes que recordar:
• La primera línea de su script debe especificar a qué intérprete enviar las instrucciones.
Esto se hace con una cadena especial llamada "shebang" (pronunciada "shuh-bang"), la
cual se ve así: #!. A la shebang le sigue un nombre de un intérprete para este script. Así,
por ejemplo, para usar bash como su intérprete usted debería usar #!/bin/sh o
#!/bin/bash. La mayoría de los scripts sólo usan #!/bin/sh. Al referirse al intérprete como
#!/bin/bash se habilitan otras características, pero se limita la compatibilidad del script con
los sistemas antiguos de Unix y rara vez es necesario.
• Antes de ejecutar un script, usted debe habilitar el permiso "ejecutable" en él (de lo
contrario, es sólo un archivo de texto). El comando para esto es chmod u+x
<scriptname>. Le otorga (y sólo a usted) permiso para ejecutar este script justo como
usted haría con otro comando. El comando chmod se tratará en detalle más adelante en
esta clase.
• Si creó un script llamado foo.sh en su directorio de inicio y justo después tecleó foo.sh
obtendría el mensaje de error "no existe tal directorio o archivo". Esto se debe a que
cuando teclea un comando hay una serie de directorios en donde Linux busca ese
comando. Estos directorios se conocen colectivamente como su RUTA y, por razones de
seguridad, su RUTA nunca incluye el directorio actual. Para resolver este problema tiene
dos alternativas:
1. Usted puede especificar de modo explícito la ubicación del script al teclear
~/foo.sh o ./foo.sh ("." siempre se refiere al directorio actual).
2. Puede colocar el script en un directorio que sea parte de su RUTA. Los usuarios
que no son root no tienen permiso para colocar archivos en la mayoría de estos
directorios, pero todos los usuarios tienen un bin personal, al cual pueden escribir
en su directorio de inicio. Por lo tanto, si foo.sh fuera movido a ~/bin se podría
ejecutar al teclear simplemente foo.sh en la línea de comandos. Esta es la técnica
preferida.
Veamos un simple ejemplo. Suponga que usted es un administrador que necesita ver con
frecuencia qué usuarios han iniciado sesión en el sistema. Esta información puede obtenerse al
ejecutar el comando w (sí, eso es todo) pero mientras esto proporciona un buen resumen de quién
ha iniciado sesión, no imprime la hora en la que se tomó esta instantánea de la actividad del
usuario. Otro comando, llamado date imprime la fecha y hora actual, pero no la información del
usuario. Si solo usted pudiera combinar esos dos comandos...
146
[student@station ~]$ cat ~/bin/wdate.sh
#!/bin/sh
date
w
[student@station ~]$ chmod u+x ~/bin/wdate.sh
[student@station ~]$ wdate.sh
Thu Jul 14 12:13:54 PDT 2005
12:13:54 up 2 days, 12:50, 8 users, load average: 0.35, 0.27, 0.18
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
student_a tty1 - Mon23 ?xdm? 2:43m 3.06s /bin/bash
student tty2 :0.0 Tue17 0.00s 2.19s 0.00s /bin/sh /
home/student/bin/wdate.sh
[student@station ~]$
Observe que el script había sido colocado en ~/bin y era ejecutable antes de ejecutarse como un
comando normal. Al ejecutar date seguido por w, ¡nos da dos comandos por el precio de uno!
Obviamente, este script podría luego modificarse para ejecutar un número arbitrario de comandos
seguidos. De hecho, los scripts pueden ser mucho más eficaces que apenas una lista de
comandos y pueden ser programas complejos en su propio derecho. El material complementario
de esta lección describe técnicas avanzadas para scripts y pueden habilitarse a discreción de su
instructor. Por ahora, concéntrese en dominar los scripts básicos como una valiosa técnica de
almacenamiento. La regla de oro del administrador es que si usted tiene que hacer una tarea más
de dos veces,¡haga un script!
Valores de retorno
Cada proceso en Linux tiene un ciclo de vida. Todos los procesos comienzan a solicitud de otro
proceso (a menudo shell). El proceso solicitado se denomina padre, y el proceso recién nacido el
hijo. El proceso hijo suele realizar sus deberes (incluyendo generar sus propios hijos), y luego elige
morir. Un proceso de salida deja atrás una pequeña parte de información cuando muere, llamado el
valor de retorno del proceso o estatus de salida. El proceso padre es responsable de reunir los
valores de retorno de los hijos muertos.
Los valores de retorno vienen en forma de enteros los cuales van de 0 a 255. Los programas
pueden escoger líbremente el valor al salir [1]. A menudo, lo que significan las implicaciones por
valores de retorno son parte de una interfaz de un programa bien definido y están documentadas
en la página man del programa, (si no está familiarizado con el comandodiff, la sección de
"DIAGNÓSTICO" de su página del manual ofrece un ejemplo). Una convención de Linux (y Unix)
es que un programa devuelve en 0 para implicar "éxito" en lo que estaba intentando hacer, y un
valor de retorno de no cero que implica algun tipo de error.
La shell bash almacena el valor de retorno del comando ejecutado anteriormente en una variable
especial llamada ?. Infortunadamente, no hemos descrito aún todas las variables de shell (eso
sigue luego), pero observemos que el valor de esta variable (por ejemplo, el valor de retorno del
programa ejecutado antes), puede examinarse con el comando echo $?.
En el siguiente ejemplo, el comando ls se utiliza para examinar los permisos del archivo
/etc/passwd. Dado que el comando "funciona", el comando ls devuelve un valor de retorno de 0.
147
[elvis@station elvis]$ ls -l /etc/password
ls: /etc/password: No such file or directory
[elvis@station elvis]$ echo $?
1
Dado que el comando "no funcionó", devolvió un valor de retorno de 1. Devolver un 0 de éxito y un
1 cuando se presenta cualquier tipo de error, es una conducta normal. Si una página man del
programa no menciona otra cosa, generalmente se puede asumir esta conducta.
La shell bash usa &&y || para unir dos comandos de modo condicional. Cuando los comandos se
unen de este modo, el primero siempre se ejecutará. El segundo comando puede que se ejecute o
no dependiendo del valor de retorno del primer comando. Por ejemplo, un usuario puede desear
crear un directorio y luego mover un nuevo archivo dentro de ese directorio. Si la creación del
directorio fracasa, entónces no hay razón para mover el archivo. Los dos comandos pueden
acoplarse de la siguiente forma.
Al acoplar los dos comandos con &&, el segundo comando sólo ejecutará el primer comando que
tuvo éxito (por ejemplo, tuvo un valor de retorno de 0). Esto es similar a la operación "and" que se
encuentra en varios lenguajes de programación. En el ejemplo anterior, el comando mkdir tuvo
éxito y luego el archivo se movió. ¿Qué sucedería si el comando mkdir fracasara?
[elvis@station elvis]$ echo "one two three five seven eleven" >
primes.txt
[elvis@station elvis]$ mkdir /tmp/mostly/boring && mv primes.txt
/tmp/mostly/boring
mkdir: cannot create directory `/tmp/mostly/boring': No such file or
directory
[elvis@station elvis]$ ls
primes.txt
Dado que el comando mkdir fracasó (el directorio /tmp/mostly no existá, por lo tanto el directorio
/tmp/mostly/boring no se pudo crear), bash no trató de ejecutar el comando mv.
Igualmente, los comandos múltiples pueden combinarse con ||. En este caso, bash ejecutará el
segundo comando sólo si el primer comando "fracasa"(tiene un valor de retorno diferente a cero).
Esto es igual al operador "or" que se encuentra en lenguajes de programación. En el siguiente
ejemplo, elvis intenta cambiar los permisos en un archivo. Si el comando fracasa, un mensaje para
ese efecto se imprime en la pantalla.
148
[elvis@station elvis]$ chmod 600 /tmp/boring/numbers.txt || echo "chmod failed."
[elvis@station elvis]$ chmod 600 /tmp/mostly/boring/primes.txt || echo "chmod failed"
chmod: failed to get attributes of `/tmp/mostly/boring/primes.txt': No such file or
directory
chmod failed
En el primer caso, el comando chmod tuvo éxito, y no se imprimió ningún mensaje. En el segundo
caso, el comando chmod fracasó (porque el archivo no existía) y apareció el mensaje "chmod
failed" (aparte del mensaje de error estándar de chmod).
Ejemplos
Echoing $? twice
El usuario elvis acaba de aprender sobre los valores de retorno, y está examinando los valores de
retorno de varios comandos. Después de ejecutar (sin éxito) el comando ls, encuentra que, como
era de esperar, la variable de bash ? contiene 1. Al examinar la variable otra vez, se da cuenta que
ahora contiene un 0. ¿Qué hizo cambiar el valor?
Recuerde que la variable de bash ? contiene el valor de retorno de los comandos ejecutados más
recientemente. En el primer caso, éste contenía el valor de retorno (sin éxito) del comando ls. En el
segundo caso, éste contenía el valor de retorno del comando echo (con éxito).
Visualización de recordatorios
El usuario ahora quiere desarrollar un esquema en donde pueda dejar recordatorios y que
automáticamente aparezcan al iniciar una shell. Crea un archivo en el directorio de inicio llamado
reminders con el texto brush your teeth y agrega la siguiente línea a su archivo ~/.bashrc.
cat /home/elvis/reminders
Luego prueba su configuración de modo manual iniciando una nueva shell bash.
149
[elvis@station elvis]$ echo "brush your teeth" > reminders
[elvis@station elvis]$ nano .bashrc
[elvis@station elvis]$ cat .bashrc
# .bashrc
cat reminders
[elvis@station elvis]$ bash
brush your teeth
[elvis@station elvis]$ exit
exit
[elvis@station elvis]$
Todo parece funcionar bien, hasta que elvis sigue su consejo de limpieza y borra su archivo
reminders. La próxima vez que inicia una shell se encuentra con lo siguiente:
Dándose cuenta que le gustaría ejecutar el comando cat sólo si el archivo reminders existe, edita
la línea que agregó a su archivo .bashrc con lo siguiente:
Ahora el comando cat sólo se ejecutará si el comando ls tiene éxito, porque el archivo reminders
existe, (¿hay una mejor forma de hacer esto? Sí, pero aún no hemos aprendido lo suficiente para
hacerlo.)
Ejercicios en línea Lab Exercise Objetivo: Ejecutar comandos dentro de una subshell.Estimated
Time: 10 mins.
Especificaciones
1. Agregue una sola línea al final del archivo .bashrc en su directorio de inicio. La línea debe
ejecutar los comandos cd /usr y ls en una sola subshell , (al ejecutarla, el directorio de
trabajo actual de su shell no se afectará.)
Si se implementa correctamente, al iniciar una nueva shell debería ver una salida similar a la
siguiente:
150
[elvis@station elvis]$ bash
bin etc include lib local share tmp
dict games kerberos libexec sbin src X11R6
[elvis@station elvis]$
1. Un archivo ~/.bashrc cuya última línea ejecute los comandos cd /usr y ls en una sola
subshell.
Limpieza
151
Variable de bash
Conceptos clave
Discussion
La shell bash le permite a los usuarios establecer y hacer referencia a las variables de shell. Una
variable de shell es simplemente un valor con nombre que la shell recuerda. Las variables de shell
se pueden utilizar en comandos y scripts de shell y pueden también referenciarse en programas
como opciones de configuración. Por ejemplo, el cliente de correo electrónico mutt ejecuta un
editor externo al escribir un mensaje. Por defecto este editor esvi. Sin embargo, antes de ejecutar
vi comprobará si una variable llamadaEDITOR se ha establecido. Si se ha establecido, entonces el
comando definido por EDITOR se utiliza en lugar de vi. La mayoría de los programas que lanzan
editores externos funcionan del mismo modo.
Hay dos tipos de variables de shell: variables locales y variables de entorno. Una variable local
existe solo dentro de la shell en la cual se crea. Las shells hijas heredan las variables de entorno
como cuando se lanza una terminal después de iniciar sesión. Primero, veremos cómo definir una
variable local, luego hablaremos acerca de cómo definir variables de entorno incluyendo la bash
misma.
El configurar las variables locales es bastante sencillo. En el siguiente ejemplo, prince establecerá
la variable A con el valor apple.
Si usted sigue, asegúrese de no dejar ningún espacio a los lados del signo =. Ahora la shell se
"cuelga"a esta asociación por todo el tiempo que exista la shell (o hasta que se anule
explícitamente, ver a continuación). Cada vez que prince quiera usar el valor "apple", puede usar la
variable A en su lugar, iniciando la variable con el signo ($), como en el comando echo mostrado
abajo. Esto se llamadesreferenciar la variable A.
La variable se puede utilizar en cualquier parte de la línea de comandos (o en los scripts de shell).
¿Qué sucede si prince, en lenguaje colorido, decidiera escribir unas cuantas líneas acerca de las
152
manzanas (o apples en inglés) y las almacenara en un archivo llamado ode_to_apple.txt. La
siguiente línea podría ayudarlo a empezar:
Cuando la shell bash examinó la línea de comandos, remplazó $A por apple. Estos son los
conceptos básicos de las variables de shell. Las variables se establecen y se configuran con una
sintaxis VAR=valor y se desreferencian con una sintaxis $VAR.
¿Qué puede utilizarse como nombres de variables? Los nombres de variables pueden ser
cualquier cadena de caracteres alfanuméricos (A-Z, a-z, 0-9), y el guión bajo (_), pero no pueden
comenzar por un número. Las variables de shell distinguen mayúsculas de minúsculas, como se
muestra a continuación.
En el primera impresión en pantalla, $B fue remplazado por el valor banana. ¿Cómo fue
desreferenciado $b? Si se le pide a la shell desreferenciar una variable no establecida, ésta
remplaza la referencia de la variable con una cadena vacía (en otras palabras, con nada). Dado
que b se considera como una variable diferente a B, y que la variable b nunca ha sido asignada, la
shell remplaza la referencia $b con nada. Por protocolo, las variables suelen definirse con
mayúsculas, pero esto no es más que protocolo.
¿Cuál puede ser el valor de la variable? Cualquier cosa. El truco se presenta en la asignación.
Cuando se asignan las variables, la sintaxis es nombre=valor, sin dejar espacios. ¿Qué sucedería
si prince quisiera que la variable FRUIT apuntara a la frase mushy bananas?
Nos hemos tropezado con una sintaxis avanzada para configurar las variables, es decir
nombre=valor comando, el cual establece la variable name sólo para la ejecución del comando
especificado. La shellbash obedientemente estableció la variable FRUIT en el valor mushy y fue a
ejecutar el comando bananas, con resultados esperables. Pero esto no es lo importante, lo
importante es que si quiere establecer una variable a un valor que contenga espacios, debe incluir
el valor entre comillas.
153
[prince@station prince]$ FRUIT="mushy bananas"
[prince@station prince]$ echo $FRUIT is my favorite fruit
mushy bananas is my favorite fruit
Con esta modificación, prince obtiene la conducta correcta desde la shell bash, si no la gramática
inglesa correcta.
Cuando se desreferencian las variables, el nombre de la variable puede marcarse con corchetes {},
si es necesario. Por ejemplo, ¿qué sucedería si arriba, prince hubiera querido guardar su poema
dentro de un archivo llamado apple_ode.txt? El ensaya el primer método obvio, en el mismo
directorio como se muestra arriba.
¿Dónde está el archivo apple_ode.txt? Un par de cosas han conspirado contra prince. Primero, la
shell bash desreferenció el nombre correcto de variable, pero no el que prince quería. ¿De qué
puede estar compuesta una variable? De caracteres alfanuméricos y minúsculas. La shell bash
apuntó a la variable (sin inicializar) A_ode (a nada) y creó el archivo resultante .txt. En segundo
lugar, debido a que .txt comienza por un ., es un "archivo oculto", así como ls -a lo revela.
[prince@station prince]$ ls -a
. .bash_profile .gtkrc .plan
.. .bashrc .kde .txt
.bash_history .gnome-desktop ode_to_apple.txt .viminfo
.bash_logout .gnupg .pgpkey .xauthizv2EF
[prince@station prince]$ cat .txt
Oh, I like them squishy
El usuario prince puede salir de esta situación utilizando corchetes para delimitar el nombre
deseado de la variable.
Utilizar corchetes para delinear nombres de variable siempre es correcto y en algunos casos, es
necesario.
Al terminar con una variable, la variable se puede desligar de su valor con el comando unset.
[prince@station prince]$
154
Variables de Bash
El siguiente cuadro lista algunas variables que se establecen automáticamente con la shell bash.
Estas variables son de sólo lectura y no pueden ser configuradas por el usuario.
Estas variables son establecidas por la shell para proveer información. Estas no se pueden
reasignar por el usuario, así como prince lo descubre a continuación.
Las siguientes variables son inicializadas por la shell bash, pero pueden ser reasignadas.
Variables de entorno
El configurar y resolver variables debería ser bastante sencillo, (siempre y cuando se acuerde de
los espacios). Ahora presentaremos un concepto un poco más sutil y mucho más útil: variables de
entorno.
Así como la shell bash permite asignar parejas de valores-nombre llamados variables de shell, el
kernel de Linux permite a cualquier proceso definir las parejas nombre-valor llamadas variables de
entorno. Estas variables son una parte del proceso almacenado en el kernel, simplemente como el
id del proceso, el id del usuario y el directorio actual de trabajo son parte del proceso. Lo más
importante es que cada vez que se inicie un proceso (tal como la shell bash iniciando el comando
ls), las variables de entorno son heredadas por el proceso hijo. Esto le permite a los usuarios
155
utilizar la shell bash para crear o modificar una variable de entorno y luego todos los comandos
iniciados por la shell heredarán esa variable.
¿Cómo creamos variables de entorno dentro de la shell bash? Primero, una variable de shell se
crea y luego la variable de shell es "promovida" a una variable de entorno mediante el comando
export, (la variable será luego exportada a cualquier proceso hijo futuro). Considere el siguiente
ejemplo:
Las variables de entorno suelen utilizarse para configurar comandos con información acerca de
configuraciones locales o en otras palabras, la información acerca del entorno local. A manera de
ejemplo, muchos comandos buscarán una variable de entorno llamada LANG para determinar el
lenguaje del usuario y modificar su salida como corresponde.
156
[prince@station prince]$ echo $LANG
en_US.UTF-8
[prince@station prince]$ date
Fri Aug 1 11:54:24 EDT 2002
[prince@station prince]$ LANG=de_DE
[prince@station prince]$ date
Fre Aug 1 11:54:53 EDT 2002
[prince@station prince]$ LANG=es_ES
[prince@station prince]$ date
vie ago 1 11:55:09 EDT 2002
Al establecer la variable de entorno LANG para de_DE, la abreviatura habitual para el día "viernes"
en alemán entonces se convierte en la abreviación alemana por regla. Al establecer LANG como
es_ES, los efectos son incluso más obvios, puesto que las abreviaturas de los días y meses han
cambiado al español (como también las convenciones de las mayúsculas).
Un punto importante que merece reformularse. El comando date no cambió la conducta porque el
comando bash tenía una variable de entorno denominada LANG (directamente). El proceso al
ejecutar el comando date modificó su salida porque tenía su propia variable de entorno llamada
LANG. Esto simplemente sucedió para heredar esta variable de la shell bash. Todos los procesos
tienen variables de entorno, no sólo shells.
¿Por qué prince no tuvo que exportar explícitamente la variable LANG? La variable ya es una
variable de entorno configurada por los scripts de arranque. Una vez que una variable es una
variable de entorno, se puede modificar ( y suprimir) mediante la misma sintaxis de las variables de
shell.
A menudo, los usuarios utilizan una sintaxis más corta para crear y exportar una variable de
entorno:
Con este sólo comando, prince ha creado, asignado y exportado la variable EDITOR.
Listado de variables
La shell bash provee dos comandos para listar variables definidas. El comando set, sin
argumentos, lista las variables de shell y las variables de entorno asociadas con la shell, mientras
que el comando env, otra vez sin argumentos, lista sólo variables que han sido exportadas al
entorno.
157
[prince@station prince]$ set
BASH=/bin/bash
BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release"
[5]="i386-redhat-
linux-gnu")
BASH_VERSION='2.05b.0(1)-release'
COLORS=/etc/DIR_COLORS.xterm
COLUMNS=80
...
[prince@station prince]$ env
HOSTNAME=localhost
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
USER=prince
MAIL=/var/spool/mail/prince
...
El siguiente cuadro lista algunas variables de entorno que con frecuencia se utilizan para
personalizar un entorno de usuario.
Variable Uso
TERM Especifica la configuración de bajo nivel de la terminal del usuario. La variable es más
relevante al utilizar una consola de línea serial ("terminal tonta") para acceder al
sistema.
PATH Especifica los directorios para buscar archivos ejecutables en ellos.
DISPLAY Especifica qué clientes del servidor X deberían usar el entorno gráfico.
LANG Especifica el lenguaje preferido para los programas internacionalizados.
EDITOR Muchos programas dependen de un editor externo para la entrada de parte del
usuario. A menudo, el editor por defecto es vi. Si la variable de entorno EDITOR está
establecida, el editor especificado se utilizará en su lugar.
PRINTER La mayoría de los comandos que envían o administran trabajos de impresión
examinarán esta variable de entorno para determinar la impresora predeterminada.
Ejemplos
El usuario prince desea mantener al día los aspectos relacionandos con el software de Open
Source y suele utilizar los enlaces de texto del navegador web links para visitar
http://www.redhat.com/opensourcenow/key_issues.html. En lugar de teclear de modo repetitivo la
URL, prince modifica su archivo ~/.bashrc, para que la URL sea almacenada en la variable
OSNISSUES. Ahora prince puede referirse a la página web de un modo más fácil.
158
[prince@station prince]$ vim .bashrc
[prince@station prince]$ cat .bashrc
# .bashrc
OSNISSUES=http://www.redhat.com/opensourcenow/key_issues.html
[prince@station prince]$ bash
[prince@station prince]$ links $OSNISSUES
Dado que prince está utilizando un computador sin conexión directa al internet, debe configurar su
navegador de red para usar el servidor proxy encontrado en la dirección IP 10.1.1.1 y en el puerto
8080. Mientras trata de entender cómo establecer un servidor proxy para el navegador de texto
links, se encuentra con lo siguiente en la página de manual links(1).
PROTOCOL_proxy Links supports the use of proxy servers that can act
as firewall gateways and caching servers. They are
preferable to the older gateway servers (see
WWW_access_GATEWAY, below). Each protocol used by
Links, (http, ftp, gopher, etc), can be mapped sepa-
rately by setting environment variables of the form
PROTOCOL_proxy (literally: HTTP_proxy, FTP_proxy,
HTTPS_proxy, etc), to "http://some.server.dom:port/".
Con el fin de establecer el servidor proxy, agrega la siguiente línea a su archivo ~/.bashrc.
HTTP_proxy=http://10.1.1.1:80
Prince inicia una nueva shell (para que el archivo .bashrc sea leído) y trata de tener acceso a la
página web de Open Source.
159
El navegador de enlaces aparentemente no está tratando de usar el servidor proxy. Cuando prince
revisa sus pasos, se da cuenta que aunque configuró la variable http_proxy, olvidó exportar la
variable. Dado que la variable es una variable de shell establecida y no una variable de entorno, no
es heredada por el proceso links. Prince edita la línea que agregó a su archivo .bashrc,
agregándole la palabra exportar:
export HTTP_proxy=http://10.1.1.1:80
De nuevo inicia una nueva shell (para que lea el archivo .bashrc otra vez) y ensaya una vez más.
Dado que la variable http_proxy ahora es exportada como una variable de entorno, es heredada
por el proceso links, y links usa con éxito el servidor de proxy para contactar el sitio. Puesto que
prince incluyó la línea en su archivo ~/.bashrc, la variable de entorno se configurará
automáticamente cada vez que inicie una nueva shell, y prince no necesita preocuparse por esto.
Cuando la shell bash examina una línea de comandos, asume que la primera palabra es el nombre
del programa que se va a ejecutar. Luego debe ubicar el archivo que contiene el programa en el
sistema de archivos. Dado que la búsqueda de un archivo ejecutable, por ejemplo, ls en todo un
sistema de archivos, tardaría mucho, la shell busca en la variable de entorno PATH para obtener
instrucciones.
La variable de entorno PATH contiene una lista de directorios en los cuales deberían buscar los
archivos ejecutables, separados por una coma:
Considere ejecutar el comando xclock, el cual comienza por un reloj en el entorno gráfico X. Por
medio de la variable PATH, bash primero busca el archivo /bin/xclock, y al no encontrarlo, busca
entonces /usr/bin/xclock. El proceso continua hasta encontrar el archivo ejecutable
/usr/bin/X11/xclock.
160
No todos los archivos ejecutables en el sistema residen en directorios que están en la lista por su
variable de entorno PATH. Se dice que algunos programas viven "fuera de su ruta". Sin embargo,
el hecho que un programa viva fuera de su ruta, no significa que no pueda ejecutarse. Significa que
usted debe especificar el comando mediante una referencia absoluta.
A manera de ejemplo, el comando lsof lista los archivos actualmente abiertos en el sistema, (el
nombre se deriva del inglés LiSt Open Files.) Dado que este comando lo suelen utilizar
administradores de sistemas, y no usuarios "normales", el comando vive en el directorio /usr/sbin,
el cual se adhiere "fuera del" PATH por defecto en Red Hat Enterprise Linux. El usuario prince
desearía usar el comando para listar todos los archivos actualmente abiertos que el proceso init
está utilizando.
Al examinar su PATH, el directorio /usr/sbin no está listado, así que prince trata de ejecutar el
comando como una referencia absoluta.
Dado que él preferiría poder ejecutar el comando directamente, prince desearía agregar el
directorio /usr/sbin a su ruta. Utiliza un truco estándar de Linux (y Unix) para agregar el directorio a
su ruta.
El comando puede ser pensado como si se dijera "establezca la variable PATH"sea cualquiera que
sea actualmente, pero luego agregue :/usr/sbin. Tras examinarlo, la variable PATH ha agregado el
directorio /usr/sbin y prince ahora puede listar los archivos fácilmente.
161
Expansión de la línea de comandos
Conceptos clave
Discussion
Generalidades
Antes de ejecutar un comando, la shell bash ejecuta varias expansiones en la línea de comandos.
Varios tipos de expansiones de bash, tales como la expansón del nombre de ruta (comodín) y la
expansión de variables ya se han descrito. El siguiente cuadro lista los tipos de expansiones bash
con una descripción de cada una a continuación.
La expansión del historial, la cual se invoca con un signo de exclamación, se describió de modo
extensivo en una lección anterior. Aquí se incluye debido al contexto.
Expansión de llaves
La expansión de llaves expande una sola palabra en palabras múltiples, sustituyendo uno de los
elementos en "llave" para cada palabra. Por ejemplo, la expresión {c,b,r}at se expandiría en tres
palabrascat bat rat. La expansión de llaves se utiliza para referirse (o crear) archivos que tienen
prefijos, postfijos o componentes de ruta comunes, (recuerde que varios ejercicios de laboratorio
162
han utilizado expansión de llaves para crear rápidamente un gran número de directorios o archivos
y luego subdirectorios dentro de ellos).
|-- chap01/
|-- chap02/
|-- chap03/
`-- chap04/
4 directories, 0 files
|-- chap01/
| |-- html/
| `-- text/
|-- chap02/
| |-- html/
| `-- text/
|-- chap03/
| |-- html/
| `-- text/
`-- chap04/
|-- html/
`-- text/
12 directories, 0 files
En el primer comando mkdir, la palabra entre corchetes se expande a cuatro directorios chap01,
chap02, chap03, y chap04. En el segundo comando mkdir, la palabra con doble corchete se
expande a ocho directorios chap01/html, chap01/text, chap02/html y así sucesivamente.
Expansión de tilde
Quizás este es el concepto más sencillo de expansión, la expansión de tilde, el cual expande un
~nombredeusuario para el usuario del directorio de inicio del nombredeusuario, como se listó en el
archivo/etc/passwd (o la base de datos apropiada del usuario). A continuación, prince utiliza la
expansión tilde para referirse a su directorio propio y a los directorios de elvis, y luego un
subdirectorio del directorio de inicio de elvis.
163
[prince@station prince]$ ls -ld ~ ~elvis
drwx-----x 15 elvis elvis 4096 Jul 21 17:41 /home/elvis
drwx-----x 9 prince prince 4096 Aug 4 06:58 /home/prince
[prince@station prince]$ ls -l ~elvis/pub
total 4
drwxrwxr-x 2 elvis music 4096 Jul 13 05:46 music
A menudo en este curso y en otros textos, la tilde se utiliza para implicar que un archivo debería
existir en el directorio de inicio del usuario, tal como el archivo ~/.bash_history. Ahora podemos ver
la razón de esta convención.
Expansión de variables
Expansión aritmética
La shell bash suele considerarse un entorno deficiente para cálculos numéricos y los operadores
aritméticos tales como +, -, *, y / en la línea de comando no tienen el significado matemático
habitual. Sin embargo, la shell bash trata de manera especial texto delimitado con una sintaxis $
((...)). Primero, las variables se tratan como enteros numéricos cuando resulte apropiado, y
segundo, los operadores matemáticos estándar como por ejemplo +, -, *, y / se tratan como tal. La
shell bash "expandirá" toda la expresión y la remplazará por el resultado numérico. Los operadores
aritméticos son los mismos del lenguaje de programación C y están totalmente documentados en la
página de manual bash(1) bajo "EVALUACIÓN ARITMÉTICA".
En el siguiente ejemplo, prince utilizará una expansión aritmética para calcular el área de un
rectángulo.
Sin embargo, las limitaciones de cálculos numéricos se descubren rápidamente cuando prince trata
de volver a calcular el área mediante un número de punto flotante.
Sustitución de comandos
Quizás de las expansiones más complejas y útiles, la sustitución de comandos permite a los
usuarios ejecutar comandos arbitrarios en la subshell e incorporar los resultados dentro de la línea
164
de comandos. La sintaxis de la"vieja escuela" para la sustitución de comandos es encerrar el
comando entre "acentos graves" (la comilla simple inclinada hacia la izquierda que se encuentra en
la misma tecla de ~, cerca de 1 en la mayoría de los teclados), y el comando de sustitución suele
denominarse "sustitución de acentos graves". La sintaxis más moderna soportada por la shell bash
es similar a la expansión aritmética, pero con solo un par de paréntesis: $(subcomando)
Como ejemplo de una sustitución de comandos, prince desearía crear un directorio que contenga
la fecha en su nombre. Después de examinar la página de manual date(1), crea una cadena de
formato para generar la fecha en un formato compacto.
O pudo haber combinado las ventajas de la sustitución de comandos y la sustitución del historial
como se muestra a continuación.
Caracter Coinciden
* 0 ó más caracteres
? exactamente un caracter
[...] exactamente uno de los caracteres incluídos
[^...] exactamente uno de los caracteres excluídos
La shell bash usa varios caracteres de puntuación que se encuentran en el teclado para ejecutar
diferentes tipos de expansiones, redirecciones y otra clase de actos de expertos. Aunque es eficaz,
hay situaciones en que los usuarios desean utilizar uno de estos caracteres sin la invocación de
165
ningún tipo de conducta especial. Parafraseando a Sigmund Freud, "A veces un signo dólar es
sólamente un signo de dolar."
La shell bash proporciona tres mecanismos para evitar que los caracteres sean interpretados por
la shell, escapando, utilizando comillas dobles o sencillas.
Sintaxis Efecto
\ Impide que el siguiente caracter sea interpretado por la shell.
"..." Impide que los caracteres incluídos sean interpretados por la shell, exceptuando los
caracteres $, !, y ` (acento grave).
'...' Impide que todos los caracteres incluídos sean interpretados por la shell.
Considere los siguientes ejemplos, donde prince está tratando de imprimir en pantalla. En el primer
caso, prince define la variable CAR, y trata de imprimir la línea sin comillas.
SIn comillas, bash interpretó los caracteres > y < como solicitudes para redirigir la salida (y
entrada) del comando. La shell se confundió cuando se le pidió redirigir la salida dos veces. El
usuario prince, trata de nuevo, esta vez utilizando comillas dobles.
En este caso, las comillas dobles protegieron los caracteres < y >. Sin embargo, el signo de dólar,
todavía se interpreta como marcador para una variable. El usuario prince intenta de nuevo con
comillas sencillas.
En este caso, todos los caracteres de puntuación fueron protegidos de la interpretación de la shell.
Como una alternativa, los caracteres pueden escaparse individualmente con una barra invertida
precedente.
166
Como hemos visto, bash hace uso de una variedad de signos de puntuación relacionados con
comillas, asignando a cada uno un propósito diferente. Los tres estilos de comillas se ilustran con
el comando echo de abajo. Con el fin de reforzar las diferencias, los tres estilos de comillas se
describen a continuación.
Las comillas dobles se utilizan en situaciones donde usted desearía tratar la mayoría de la
puntuación literalmente o combinar palabras en un sólo símbolo, pero aún puede hacer uso
de variables, sustitución de comandos y sustitución de historial.
Las comillas sencillas son las más poderosas y se utilizan en situaciones similares a las
comillas dobles cuando quiere que toda la puntuación, incluyendo las variables y la
sustitución de comandos, se traten literalmente.
Los acentos graves son básicamente diferentes a las comillas simples o dobles, no son
para citar. Estos acentos se utilizan para invocar la sustitución de comandos en el texto
incluido.
Hemos visto que bash se aplica a un gran número de expansiones de línea de comandos antes de
que un comando se ejecute. La frase incluye una sutileza que no siempre es apreciada y puede
algunas veces llevar a confusiones. Las expansiones de shell se presentan antes de que el
comando se ejecute. A veces, algunos los comandos esperan argumentos que contienen
caracteres especiales para la shell bash. Un ejemplo es el comando find. Si no se tiene cuidado al
utilizar comillas o escapar los caracteres especiales, bash podría "expandirlos" antes de que el
comando los vea. El siguiente ejemplo del comando find en acción podría ayudar.
Al iniciar desde un directorio vacío, prince ejecuta find para buscar todos los archivos terminados
en .conf en el directorio /etc.
167
Pasando por alto algunas quejas acerca de los directorios inaccesibles, el comando funciona.
Luego, prince crea los archivos a.conf y b.conf en el directorio local e intenta de nuevo.
¿Por qué el comando que funcionó hace apenas unos segundos no funciona ahora? La respuesta,
como podría esperarse, tiene que ver con la expansión de línea de comandos.
¿Qué hace primero bash? Aplica la expansión de línea de comandos. Después de examinar el
directorio local y hallar los archivos a.conf y b.conf, la shell remplaza el comodín *.conf con los
nombres de archivo coincidentes, a.conf b.conf. Esta es una expansión de nombre de ruta
bastante antigua. Después de la expansión, el comando se ve de esta manera.
Ahora bash ejecuta el comando, el cual genera un mensaje de error (porque la opción -name no
pudo manejar dos argumentos).
Volviendo al primer comando, ¿por qué funcionó? Al implementar la expansión del nombre de ruta,
la shell bash intenta ayudar a la gente. Si un comodín "falta " (por ejemplo, ningún archivo coincide
con la expresión especificada), bash conserva el comodín. En el primer caso, como ninguno de los
archivos coincidió con *.conf, bash pasó el argumento al comando find como está escrito. [1]
¿Cuál es la forma correcta de manejar la situación? Usar comillas o escapar los caracteres
especiales, como se muestra a continuación:
Debido a que se ha utilizado el * , la shell bash no intentará realizar una expansión de nombre de
ruta y el comando funciona como se desea. La lección es: si está pasando un caracter especial
168
dentro de un comando, usted debería proteger el caracter con comillas (o un escape de barra
invertida).
Ejemplos
ogg/
|-- blues
| `-- playlist
|-- folk
| `-- playlist
|-- pop
| `-- playlist
`-- rap
`-- playlist
4 directories, 4 files
¿Pudo prince haber utilizado el comodín de archivo (expansión de nombre de ruta) en su lugar? Al
utilizar el comando mkdir, el comodín de archivo habría sido inútil porque los directorios blues, folk,
etc.., no existían. ¿Qué sucedería si prince hubiera utilizado el comodín de archivo para el
comando touch?
Los directorios blues, folk, etc., existeron, pero ninguno de los archivos playlist existia, por lo tanto
el comodiín se perdió. Para situaciones en que el archivo podría o no existir, la expansión de llaves
tiende a funcionar mejor que el comodín.
Hemos visto que la shell bash graba las pulsaciones al completar nombres de comandos o
nombres de archivos cuando se pulsa la tecla TAB. La shell bash completará nombres de usuario
y variables, cuando las palabras comienzan por los caracteres ~ o $, respectivamente. Por
ejemplo, si un usuario escribe ~el<TAB>, bash podría completar el símbolo ~elvis. De la misma
manera, $PA<TAB> podría completarse $PATH. De forma similar a la expansión del comando y
169
nombre de archivo, si los caracteres iniciales tecleados hasta el momento no especifican
únicamente una variable (o nombre de usuario), bash emite un pitido. Al pulsar dos veces el TAB
se listarán las posibles terminaciones.
En un cuaderno anterior, mencionamos que los nombres de archivo en Linux (y Unix) podrían estar
compuestos por cualquier caracter a excepción de uno (¿Recuerda cuál?[1]) En el mismo cuaderno,
se les dijo a los estudiantes que aunque se podían utilizar caracteres especiales, era mejor
evitarlos. Ahora estamos en una buena posición para ver el porqué. Suponga que prince quiere
crear un archivo único llamado Make $$$ *Fast* !!.
El comando touch accede, creando los archivos que bash le pide hacer. Primero, como los
símbolos están separados por espacios, bash los trata como cuatro palabras separadas. Luego la
shell bash aplica sus distintas expansiones a las palabras.
Una vez se han aplicado las extensiones, la shell bash invoca touch con cuatro argumentos, para
que touch obedientemente cree cuatro archivos.
¿De qué manera persuadimos a bash para que cree un archivo con nuestro rito proporcionado por
Linux de incluir espacios y puntuación en el nombre de archivo? Obviamente con comillas.
Con sólo ls, es difícil distinguir entre múltiples archivos y un archivo único con espacios en el
nombre. Un ls -l ayuda a aclarar la situación.
170
[prince@station prince]$ ls -l
total 0
-rw-rw-r-- 1 prince prince 0 Aug 31 06:19 13986$
-rw-rw-r-- 1 prince prince 0 Aug 31 06:19 *Fast*
-rw-rw-r-- 1 prince prince 0 Aug 31 06:19 l
-rw-rw-r-- 1 prince prince 0 Aug 31 06:19 Make
-rw-rw-r-- 1 prince prince 0 Aug 31 06:40 Make $$$
*Fast* !!
1. Las comillas inhiben la interpretación de los signos de puntuación como lo solicitan las
expansiones de shell.
2. Las comillas impiden la división de palabras, la cual es la forma como la shell bash
compone argumentos para los programas que ejecuta. Por ejemplo, el comando touch
one two three haría que bash ejecute el comandotouch con tres argumentos, one, two, y
three. Por el contrario, el comando touch "one two three" haría que bash pase el único
argumento del comando touch a one two three (aunque uno con espacios).
Ejercicios en línea Lab Exercise Objetivo: Usar varias sustituciones de shell bash de modo
efectivo. Tiempo estimado: 15 minutos.
Especificaciones
171
3. Un directorio llamado ~/shirts, el cual contiene exactamente 108 archivos, cada uno
de forma estilo.tamaño.color.ext. Cada nombre de archivo contiene una combinación
de los valores que aparecen en el cuadro de arriba.
172
Personalización de la shell
Conceptos clave
• La shell bash internamente implementa ciertos comandos sencillos que están muy ligados
con la conducta de la shell. Estos se conocen como los comandos incorporados.
• Los alias de shell crean comandos aparentes que expanden a texto arbitrario.
• Los alias de shell se establecen y examinan con el comando alias.
• Los alias de shell se remueven con el comando unalias.
• El intérprete de comandos de la shell bash se puede personalizar mediante la variable
PS1.
• Las banderas de shell se pueden establecer con el comando set -f y se limpian con set +f.
• Las opciones de shell se examinan, establecen y se anulan con el comando shopt.
Discussion
Esta lección se centra en las técnicas utilizadas para personalizar la shell bash, como por ejemplo
crear comandos alias, personalizar el intérprete de comandos de la shell y establecer las opciones
de la shell. La lección comienza con un tema que no es la personalización real, pero está
relacionada con la conducta de la shell, el tema de los comandos internos.
Al evaluar una línea de comandos, la shell trata la primera palabra como un comando. La shell
bash implementa algunos comandos de modo interno, lo que significa que los comandos no
existen en el sistema de archivos como un programa cargable, sino que la shell misma los
implementa. Estos comandos se conocen como comandos internos de la shell. Estos suelen ser
comandos sencillos relacionados con cambios a la shell misma.
En un cuaderno anterior, presentamos el comando which, el cual reportará en qué parte del
sistema de archivo reside el archivo ejecutable que contiene un comando en particular. A
continuación, madonna observa que el comando date es implementado por el programa que se
encuentra en el archivo ejecutable /bin/date:
¿Qué sucede cuando madonna utiliza which para buscar el archivo ejecutable que contiene el
programa cd?
173
la shell y su documentación correspondiente se puede ver mediante el comando help, el cual es en
sí mismo un comando interno de la shell.
...
El comando help entrega una versión de la información sobre la shell, menciona un par de sitios
donde la documentación de bash puede encontrarse y presenta bota una lista de comandos
internos. Observe que la lista contiene el comando cd. El comando help también se puede utilizar
para ver documentación detallada acerca de un comando interno específico.
Dado que el comando cd está ligado a la conducta de la shell, es decir, cambia el directorio de
trabajo de la shell, este es un buen candidato para un comando interno. Varios comandos que ya
ha estado utilizando, tales como cd, pwd, y echo, son en realidad internos de la shell.
Alias
Los alias permiten a los usuarios personalizar los nombres de los comandos o enlazar comandos
con las opciones o argumentos más utilizados. Una vez creados, los alias se utilizan como si
fueran cualquier otro comando.
El comando alias
Los alias se crean (y examinan) mediante el comando interno alias. Al crear alias, el comando
alias utiliza la siguiente sintaxis.
174
alias NAME=VALOR
Este comando crearía un alias denominado NOMBRE, el cual apuntaría al valor VALOR. La
sintaxis debería ser reminiscente a la utilizada para asignar variables de shell. En particular, como
en la asignación de variable, la asignación de alias no permite espacios en ningún lado del signo
de igual. Del mismo modo, dado que la sintaxis sólo espera un símbolo único después del signo
igual, las frases que contienen múltiples palabras (separadas por espacios) deben ir entre comillas.
En el siguiente ejemplo, madonna establece el alias h como un atajo para el comando head. Dado
que el alias apunta a una sola palabra (head), madonna no tiene que preocuparse por citar el valor.
Luego utiliza el nuevo alias para examinar varias de las primeras líneas del archivo /etc/services.
En el siguiente ejemplo, madonna advierte que a menudo está listando todos los procesos
ejecutándose en la máquina con el comando ps aux. Decide entonces que cada vez que ejecute
ps, prefería la salida más completa que ps aux presenta y por lo tanto establece un alias para el
comando ps.
175
En este caso, puesto que ella quiso que el alias apuntara a una frase de dos palabras (ps y aux),
necesitó encerrar la frase entre comillas (para que tras "la división de palabras", la shell trate la
frase como una sola palabra).
El comando alias también se utiliza para examinar los alias actualmente definidos. Si madonna
quisiera repasar los alias que estableció podría sencillamente ejecutar el comando alias (sin
argumentos).
El comando alias lista los alias establecidos por madonna (h y ps), como también otros alias
establecidos por los scripts de arranque bash de madonna (y son parte de la configuración
predeterminada de Red Hat Enterprise Linux).
Si se dan argumentos (sin el signo de igual), el comando alias mostrará el alias actual para el
argumento, si existe alguno:
El comando unalias
Los alias se pueden suprimir con el comando interno de la shell unalias. Para suprimir un alias,
pase el nombre de alias como un argumento al comando unalias. A continuación madonna
suprime el alias que creó anteriormente para ps.
Evaluación de alias
¿Cuándo busca alias la shell de bash ? A diferencia de las variables, no hay signos de puntuación
asociados con ninguna clase de "expansión de alias". En su lugar, la shell de bash busca alias en
donde se espera un comando (es decir, como la primera palabra en la línea de comando). Si la
primera palabra es reconocida como un alias , el alias se expande. La excepción es si el alias se
expande al comando que tiene el mismo nombre de alias en cuyo caso la shell simplemente
ejecuta la expansión y sigue adelante, (de otra manera, los usuarios podrían fácilmente crear alias
que pondrían la shell en un bucle infinito).
176
Los usuarios pueden no darse cuenta de que están usando alias en lugar del comando mismo. Un
buen ejemplo es la configuración predeterminada de Red Hat Enterprise Linux, la cual alias el
comando ls al valor ls --color=tty, (este instruye a ls para proporcionar caracteres de control
especiales que dan color a diferentes tipos de archivos, pero solo si el comando está escribiendo
en una terminal. Cuando se redirige a un archivo, no se presenta ningún color).
Ejecución de comandos
Hemos descrito varios tipos de palabras considerados por la shell bash como "comandos". Para
resumir, y proveer un contexto, la siguiente lista resume los pasos que la shell bash realiza al
evaluar la primera palabra de la línea de comandos, (el siguiente no es el algoritmo exacto, el cual
es más complicado, pero sirve como una aproximación útil).
La shell bash interactiva, mientras que repite su bucle de "escuchar", "evaluar" y "ejecutar", expide
un intérprete de comandos cada vez que vuelve a la etapa de "escuchar". El intérprete de
comandos se utiliza para contarle al usuario que la evaluación de la etapa anterior ha terminado y
que la shell está esperando intrucciones. En la configuración predeterminada de Red Hat
Enterprise Linux , el intérprete de comandos también provee más información, incluyendo el
nombre de usuario actual, nombre de la máquina y directorio de trabajo.
El comando bash en realidad tiene cuatro intérpretes de comandos diferentes los cuales se utilizan
en diferentes situaciones. Los dos más vistos son el intérprete de comandos primario, utilizado
cada vez que bash está listo para un nuevo comando y el intérprete de comandos secundario
utilizado cuando un usuario presiona la tecla INTRO, pero la línea de comandos tiene obviamente
una sintaxis inacabada (tal como unas comillas que aún no se han cerrado). A continuación
[madonna@station madonna]$ sirve de intérprete de comandos primario, mientras que> sirve de
intérprete de comandos secundario.
177
Los usuarios pueden personalizar los intérpretes de comandos de bash mediante las variables de
shell PS1 y PS2, las cuales bash usa para componer los dos prompts. El ejemplo anterior implicó
que el intérprete de comandos primario es la forma de decir de bash "Estoy esperando", y el
intérprete de comandos secundario es la forma de decir de bash "Todavía estoy esperando". Para
plantear el punto de una forma obvia, madonna personalizará sus intérpretes de comandos para
decir justo eso.
Inmediatamente tras cambiar el valor de la variable PS1, bash comenzó a utilizar el nuevo valor
como su intérprete de comandos primario.
A menudo los usuarios desearían que el intérprete de comandos también visualizara información
útil. La shell de bash permite a los usuarios insertar secuencias de escape dentro de la definición
de PS1, que remplaza con información dinámica cuando se genera el intérprete de comandos. El
cuadro a continuación resume algunas de las secuencias más comunes. Para obtener una lista
más completa, vea la página de manual bash(1).
Secuencia Expansión
\a Campana audible de la terminal
\d fecha en formato"día mes"
\h el nombre del host hasta el primer "."
\T La hora actual en formato de 12 horas HH:MM:SS
\u el nombre de usuario del usuario actual
\W el nombre de la base del directorio de trabajo actual
\! El número de historial de este comando
\$ Si el UID efectivo es 0, un #, de lo contrario un $
\nnn el caracter correspondiente al número octal nnn
La secuencia de escape \$ puede requerir más explicación. La shell de bash utiliza esta secuencia
para reproducir una característica de la shell Bourne originial (/bin/sh). El intérprete de comandos
por defecto de la shell Bourne es un dólar ($) para los usuarios estándar y un signo (#) para el
usuario root. Con la secuencia de escape \$, un valor predeterminado PS1 para todo el sistema
puede utilizarse, imitándo esta conducta original.
178
Se utilizan dos comandos internos para configurar la conducta de la shell mediante las opciones de
shell. Uno es el comando set, el cual se utiliza para modificar la conducta de shell mediante (por lo
general) banderas de una letra, y el otro esshopt, usado para configurar las opciones de la shell.
El comando set realiza una labor triple. Cuando se utiliza con la línea de comandos, como suele
ser el caso, el comando se utiliza para establecer, o anular las banderas de shell. Observe el
cuadro siguiente con las banderas más utilizadas y sus opciones. Cuando se llamado sin
argumentos, el comando set visualiza todas las variables de shell y sus valores (como se describió
en una lección anterior). El último uso del comando incorporado se utiliza en la escritura de shell y
por ahora puede hacerse caso omiso sin ningún problema.
Bandera Efecto
-f Inhabilita la expansión de nombres de ruta (comodín)
-n Lee comandos pero no los ejecuta (se usa para revisar sintaxis en los
scripts).
-o Establece la opción especificada. Algunas de las opciones más comunes
nombredeopción incluyen lo siguiente.
emacs
ignoreeof
vi
El comando set con la sintaxis normal de las opciones (tal como set -x) habilita la bandera
especificada. Para inhabilitar la bandera, remplace el guión (-) por un signo más (+) (tal como set
+x). La lista de opciones establecidas puede almacenarse en la variable de shell $-.
179
[madonna@station madonna]$ set -f
[madonna@station madonna]$ ls /etc/*.conf
ls: /etc/*.conf: No such file or directory
[madonna@station madonna]$ set +f
[madonna@station madonna]$ ls /etc/*.conf
/etc/aep.conf /etc/lftp.conf /etc/pnm2ppa.conf
/etc/aeplog.conf /etc/libuser.conf /etc/pwdb.conf
/etc/cdrecord.conf /etc/logrotate.conf /etc/resolv.conf
/etc/esd.conf /etc/lpd.conf /etc/rndc.conf
...
No se preocupe si no entiende aún los efectos de todas las banderas de shell. En su lugar,
asegúrese de saber cómo se utiliza el comando set para habilitar o inhabilitar una bandera si es
necesario. Si en una lección posterior le dijeran "esta acción puede inhabilitarse al configurar la
bandera -H de shell ", usted sabrá cómo hacerlo.
El comando bash también tiene una segunda serie de variables de configuración, las cuales se
conocen como "opciones de shell". Estas se establecen y se anulan mediante el comando shopt
donde shopt -s nombreopciónestablece la opción nombreopción, y shopt -u nombreopción
anula la opción. El comando shopt nombreopción visualiza el estado actual de la opción,
mientras que solo shopt visualiza todas las opciones de la shell. Algunas de las opciones de shell
más fáciles de entender están listadas en el cuadro siguiente.
Opción Efecto
cdspell Intenta corregir palabras mal escritas de los nombres de directorios cuando
utiliza el comando incorporado cd.
expand_aliases Habilita alias de shell
extglob Habilita sintaxis coincidente de patrones de comodines extendidos
nocaseglob No considera el caso cuando se aplican comodines de archivo.
Una vez allá, descubre que la opción de shell solo efectúa el comando interno de cd. El comando
ls, por ejemplo, que no es un incorporado de shell, no se afecta por esta opción. Después de
observar este hecho, madonna, inhabilita la opción cdspell.
180
Se estará preguntando cómo recordar todas estas opciones y cómo recordar cuáles se modifican
con set y cuáles con shopt. La respuesta es que no es necesario. Recuerde sin embargo, que hay
dos mecanismos para establecer banderas de shell y opciones de shell (set y shopt,
respectivamente) y recuerde dónde buscar información sobre cada una (el comando help y la
página de manual bash(1)).
Ejemplos
La configuración predeterminada en Red Hat Enterprise Linux proporciona varios usos ilustrativos
de alias. Tras iniciar sesión en el comando alias se revela lo siguiente.
El primer alias, l., se utiliza para listar todos los archivos ocultos (aquellos que comienzan por ".")
en el directorio actual.
[madonna@station madonna]$ l.
. .bash_profile .gconfd .gnome-desktop .xauthxLTmDk
.. .bashrc .gnome .gtkrc
.bash_history .fonts.cache-1 .gnome2 .kde
.bash_logout .gconf .gnome2_private .viminfo
Observe que la shell bash ejecuta la expansión de nombre de ruta después de expandir el alias,
para que .* sea remplazado por cada archivo en el directorio local que comienza con ".".
El segundo alias, ll, provee una forma más fácil para invocar el comando ls con su opción de línea
de comando más usada -l. El tercer alias, ls, en efecto cambia la conducta por defecto del
comando ls, para que cada invocación de ls incluya la opción de línea de comandos --color=tty.
Si consideramos cómo bash evalúa alias, alguna redundancia se descubre. Cuando un usuario
ejecuta ll, bash expande el alias a ls -l --color=tty. La shell de bash luego examina la primera
palabra de la expansión, ls, la cual es en sí misma un alias. La expansión de alias resulta en ls
--color=tty -l --color=tty. Puesto que el alias ls se expandió al comando cuya primera palabra fue
otra vez ls, bash no intenta otras expansiones de alias. Sin embargo, la expansión resultante ll
especifica dos veces --color=tty.
La bandera de shell bash "x" es útil para descubrir estos tipos de problemas. Cuando sea
habilitado, cada comando se imprime en pantalla (con un prefijo "+") después de que todos los
alias y expansiones se hayan aplicado.
181
íneas [madonna@station madonna]$ set -x
++ echo -ne '\033]0;madonna@station:~\007'
[madonna@station madonna]$ ll
+ ls --color=tty -l --color=tty
total 12
drwx------ 2 madonna madonna 4096 Aug 26 16:23 bin
-rw-rw-r-- 1 madonna madonna 76 Aug 26 16:10 hello.c
drwxr-xr-x 4 madonna madonna 4096 Jul 21 17:05 networking
++ echo -ne '\033]0;madonna@station:~\007'
[madonna@station madonna]$ set +x
+ set +x
[madonna@station madonna]$
El cuarto alias, vi, se utilliza para reasignar un comando empleado para una implementación
alterna. Uno de los editores más comunes de Linux (y Unix) es el editor vi. Red Hat Enterprise
Linux se distribuye con una versión mejorada de vi, conocida como vim (para "Vi IMproved"). Con
el fin de hacer uso transparente del editor mejorado, el comando más utilizado vi ha sido
reasignado.
El último alias crea un delimitador para el comando which, para que los alias también sean
reportados como sitios de archivos ejecutables hallados en la ruta de un usuario.
El examen de los usos de las opciones de los comandos rm, mv y cp revela que todos comparten
la opción -i que se utiliza para invocar un modo interactivo. Cuando se utiliza, estos comandos le
pedirán al usuario confirmación antes de ejecutar una operación que causaría la pérdida de
información (tal como los comandos comodines cp o mv de un archivo de destino ya existente o
cualquier uso del comando rm). El uso de la opción -i se ilustra a continuación.
Muchos administradores de sistemas establecen alias por defecto para estos comandos, para que
cada invocación de estos comandos sea una invocación interactiva.
182
[madonna@station madonna]$ alias cp="cp -i" mv="mv -i" rm="rm -i"
[madonna@station madonna]$ alias cp mv rm
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'
[madonna@station madonna]$ date > a
[madonna@station madonna]$ date > b
[madonna@station madonna]$ cp a b
cp: overwrite `b'? y
[madonna@station madonna]$ rm a b
rm: remove regular file `a'? y
rm: remove regular file `b'? y
En Red Hat Enterprise Linux, la cuenta de root tiene dichos alias establecidos por defecto. Sin
embargo, los usuarios estándar, pueden configurar estas protecciones por su cuenta si así lo
desean.
Cada uno de estos comandos también viene con la opción -f para "forzar" la conducta requerida.
Dado que la opción -f anula la opción -i y puede emplearse para evitar la aburridora interrogación
al suprimir un gran número de archivos.
La usuaria madonna quiere saber cuál de sus archivos y directorios "ocultos" en su directorio de
inicio son creados o modificados por aplicaciones que ella ejecuta. Quisiera saber una forma fácil
de controlar cuáles archivos se crean o cambian antes o después de ciertas operaciones. Ella sabe
que el comando find implementa un criterio -newer, el cual listará todos los archivos que han sido
modificados antes que un archivo especificado. Desearía crear dos alias. El primero llamado
Para crear el primer alias, primero dedica un poco de su tiempo a la lectura de la página de manual
date(1) y determina que el siguiente comando generará el nombre de archivo apropiado para el
archivo marcador de tiempo.
Para crear los alias, agrega las dos líneas siguientes a su directorio ~/.bashrc. Observe el uso de la
sustitución de comandos para determinar el tiempo actual en el primer alias.
Abre una nueva shell (para que el .bashrc modificado tenga efecto), y ensaya sus nuevos alias.
Primero utiliza ts para crear un archivo marcador de tiempo.
[madonna@station madonna]$ ts
[madonna@station madonna]$ ls
bin hello.c networking timestamp.19:39:18
183
El alias ts parece funcionar, creando el archivotimestamp.19:39:18. Luego hace clic derecho en la
ventana secundaria del escritorio Gnome y elige "Nuevo Folder" desde el menu emergente. Un
folder recién creado untitled folder aparece en su ventana del escritorio. A continuación ejecuta el
alias tsc especificando su archivo marcador de tiempo recién creado como el archivo con el que se
compara.
Como se esperaba, el alias lista todos los archivos que han sido modificado más recientemente
que el archivo marcador de tiempo especificado. Observando que un archivo titulado untitled folder
fue creado en un subdirectorio llamado .gnome-desktop, madonna asume (correctamente) que el
directorio ~/.gnome-desktop contiene todos los elementos que se muestran en el escritorio de
Gnome.
Ella quiere sondear un poco más, esta vez explorando la conducta de la papelera. Decide crear un
nuevo archivo marcador de tiempo, mover su nueva carpeta a la papelera y luego buscar archivos
modificados relativos a sus nuevo archivo marcador de tiempo.
[madonna@station madonna]$ ts
[madonna@station madonna]$ ls
bin hello.c networking timestamp.19:39:18
Asombrada, madonna no ve su nuevo archivo. Examina la hora modificada del archivo original
ejecutando un ls -l.
Extrañamente, la hora modificada del archivo implica que se ha modificado aproximadamente tres
minutos después de su tiempo de creación hallado en el nombre del archivo. Explorando aún más
madonna confirma el alias ts.
Ahora madonna entiende el problema. Vuelve a llamar la línea desde su directorio ~/.bashrc donde
definió el alias ts:
184
Aunque intentó la sustitución de comandos date para que se produjera cada vez que se invocara el
alias
Esta vez, el alias se define mediante comillas sencillas, evitando que la sustitución de comandos
sea evaluada al crearse el alias. Después de comenzar una nueva shell (para que ~/.bashrc surta
efecto), madonna confirma sus definiciones de alias.
Después de arrastrar el icono untitled folder del escritorio al icono basura, busca de nuevo archivos
modificados.
Aparentemente, la carpeta fue removida del directorio .gnome-desktop a la carpeta .Trash, (el
archivo untitled folder no es listado, porque el hecho de mover un archivo de un directorio a otro no
afecta la hora modificada del archivo, sólo las horas modificadas de los directorios.)
Ejercicios en línea Lab Exercise Objetivo: laboratorio de práctica Tiempo estimado: 15 minutos.
Especificaciones
Edite su archivo ~/.bashrc para que las shellsbash recién creadas tengan las siguientes
propiedades.
185
1. El alias dir ejecuta el comando ls -l.
2. El alias globoff inhabilita la expansión de nombre de ruta (habilitando la bandera de shell
apropiada).
3. El alias complementario globon habilita la expansión del nombre de ruta (inhabilitando la
bandera de shell apropiada).
4. Al redireccionar la salida a un archivo, la shell bash no sobrescribirá un archivo existente.
5. La shell tiene la opción de shell cdspell habilitada.
6. El comando rm es un alias para rm -i.
Ejercicio de desafio
El siguiente ejercicio debe completarse como un ejercicio de desafio. No será calificado por el
script automático de calificación.
Configure el intérprete primario para que contenga el número de historial y el código de salida del
comando previamente ejecutado, separado por un : (sin espacios). La coma debería ser la única
coma incluida en el intérprete.
Si está bien configurado, el intérprete debería tener una conducta igual a la siguiente. Observe con
cuidado la conducta del intérprete de comandos después de un comando con éxito, después de un
comando fallido, y cómo se relaciona con el número de historial del comando previamente
ejecutado.
Un archivo ~/.bashrc bien configurado, de tal forma que shells bash recién iniciadas tengan las
siguientes características.
186
Lectura de scripts de shell e inicialización de shell
Conceptos clave
Discussion
Hasta el momento en este cuaderno, hemos estado utilizando el archivo ~/.bashrc como si fuera el
único archivo que pudiera ser usado para personalizar la shell bash. Esto nos ha permitido
enfocarnos en temas, tales como los alias y expansiones de shell, sin complicarnos con detalles de
scripts e inicialización de shell, a riesgo de dejar al estudiante con la impresión de que el archivo
~/.bashrc es el único que puede utilizarse para personalizar la shell bash. Si esta es la impresión
que se ha dado, el propósito de esta lección es cambiar esa idea.
En esta lección, discutiremos cómo se pueden leer los scripts de shell y cuáles scripts se leen por
defecto en el arranque con Red Hat Enterprise Linux. El saber qué scripts son leídos en el
arranque, le permite a los usuarios aplicar automáticamente muchas de las personalizaciones
aprendidas en lecciones anteriores.
Lectura de scripts
La shell bash permite a los usuarios coleccionar múltiples comandos dentro de un sólo archivo y
luego ejecutar los comandos como si fueran tecleados directamente en ese intérprete. Esto se
conoce como leer el archivo. De modo apropiado, el comando usado para leer un archivo es el
comando interno de shell source.
Como ejemplo, blondie desearía explorar diferentes estilos de intérpretes de shell. Para ayudar a
comparar, utiliza un editor para crear un archivo de texto llamado prompts.script. Agrega varias
líneas, cada una proporcionando una definición diferente para la variable PS1. Por último, comenta
todo menos la primera línea.
187
Tras originar el archivo, la variable PS1 se modifica como si el contenido del script fuera tecleado
en la línea de comando. Este punto importante merece repetición: cuando se originan los scripts de
shell, el contenido del script se ejecuta (y puede modificarse) dentro de la shell actual.
Luego, blondie edita prompts.script, comentando la primera línea y sin comentar la segunda. Luego
lee el script otra vez.
Edita de nuevo el archivo, comentando la segunda línea y dejando de comentar la última (que
restaura su intérprete al predeterminado de Red Hat Enterprise Linux).
Como un atajo, la shell bash también tiene un comando interno llamado ., el cual es un sinónimo
para el comando source. Esta vez, blondie hace uso de su atajo al originar el archivo.
Inicialización de bash
Habiendo aprendido cómo leer scripts de shell de modo arbitrario, ahora volvemos la atención a la
inicialización de bash, la cual tiende a ser un tema demasiado complicado. Después de describir la
secuencia de arranque, el proceso será resumido en una forma más sucinta. Para comenzar a
distinguir sutilmente entre diferente tipos de shells: shells deinicio y no-inicio, y shells interactivasy
no-interactivas.
Como el nombre lo dice, las shells de inicio de sesión son la primera shell que usted ve cuando
inicia sesión en una máquina. Cuando usted inicia utilizando la consola virtual o dentro de una
máquina remota, su primera shell interactiva es una shell de inicio. Cuando inicie mediante el
entorno gráfico X, la shell no vista utilizada para empezar su inicialización X es una shell de inicio
de sesión.
188
Cada shell de por medio se conoce como una shell de no-inicio de sesión. ¿Con qué frecuencia ve
shells de no-inicio de sesión? Por todas partes. Obviamente, si usted fuera a iniciar manualmente
una subshell, ésta sería una shell de no-inicio. Cada vez que usted abre una nueva terminal en un
entorno gráfico X, la shell es una shell de no-inicio. Cada vez que usted usa la sustitución de
comandos o comandos de grupo entre paréntesis, o ejecuta scripts de shell (como se describirá en
la siguiente lección), se crea una nueva shell de inicio de sesión.
Además, las shells pueden ser interactivas o no-interactivas. Usualmente, las subshells iniciadas
de forma manual o las shells en terminales X recién abiertas, son shells interactivas. Las shells
invocadas como resultado de una sustitución de comandos y similares son shells no-interactivas. El
siguiente cuadro ayudará a distinguir los diferentes tipos de shells.
El cuadro de arriba lista los predeterminados para Red Hat Enterprise Linux. Diferentes conductas
pueden invocarse al especificar explícitamente ciertas opciones de línea de comandos. Vea la
página del manual de bash(1) para obtener mayor información.
¿Cuál es la diferencia entre una shell de inicio de sesión y una shell de no-inicio de sesión? o entre
una shell interactiva y una no-interactiva? Principalmente, las shells difieren en qué archivos de
inicialización se leen tras el inicio. A continuación, se indicará el bash de inicialización de shell
como se presenta en Red Hat Enterprise Linux.
Tras el arranque, las shells de inicio de sesión primero leen el archivo /etc/profile. En Red
Hat Enterprise Linux, este archivo inicializa varias variables de entorno tales como PATH,
USER, HOSTNAME, y HISTSIZE. El script /etc/profile luego origina todos los archivos
coincidentes al patrón /etc/profile.d/*.sh. [1]
Luego, la shell bash busca una serie de archivos en el directorio de inicio del usuario, y lee
la primera que existe. En Red Hat Enterprise Linux, el archivo por defecto es
~/.bash_profile. La version por defecto de este archivo apenas agrega $HOME/bin al PATH
del usuario, y busca y origina el archivo~/.bashrc descrito a continuación.
189
Shells de no-inicio de sesión (interactivas)
En lo que concierne al programa bash, el único archivo utilizado para personalizar shells
de no-inicio de sesión es el archivo ~/.bashrc hallado en el directorio de inicio del usuario.
En la configuración por defecto de Red Hat Enterprise Linux, la única personalización que
este archivo realiza es buscar y leer el archivo /etc/bashrc.
El archivo global /etc/bashrc realiza varias operaciones, incluso establece la usmask por
defecto del usuario y define la variable PS1 (la cual define el prompt de shell).
Las shells no-interactivas de no-inicio de sesión no leen por defecto ninguno de los
archivos de arranque (aunque esta conducta puede cambiarse estableciendo la variable de
entorno BASH_ENV. Para mayor información ver la página de manual bash(1)).
¿Por qué tanta complejidad? Al arrancar, los varios scripts de arranque leídos por shells de inicio
tienden a emplear mucho tiempo personalizando variables de entorno (tales como el PATH,
HISTSIZE del usuario, etc). No obstante, cuando las subsehells se inician, no se necesita repetir
todo este trabajo. Siempre que un proceso hijo es generado por la shell de inicio de sesión, sea
ésta una subshell u otro caso, las variables de entorno se copian automáticamente en el hijo (por el
kernel de Linux). Si la subshell luego lee los mismos scripts de arranque como su shell de inicio del
padre, el esfuerzo de inicializar variables de entorno se duplicaría sin necesidad. Por lo tanto, con
el fin de agilizar los tiempos de arranque, las shells de no-inicio intentan acortar el proceso. Otras
personalizaciones de shell, principalmente los alias, son conceptos específicos de bash, no de nivel
de kernel y deben reinicializarse cada vez que se inicie una nueva shell.
Al examinar los scripts de arranque listados arriba, observe que los archivos /etc/profile y
~/.bash_profile son leídos śolo por las shells de inicio de sesión, mientras que los archivos
190
~/.bashrc y /etc/bashrc son leídos por todas las shells (de inicio y no-inicio). Los dos archivos
anteriores suelen utilizarse para configurar variables de entorno, porque sólo tienen que ser
inicializadas una vez. Mientras que los dos últimos archivos se utilizan para personalizaciones
específicas de la shell tales como alias y opciones de shell.
Las shells no-interactivas son shells iniciadas como resultado de ejecutar un script (ver la siguiente
lección), usando paréntesis para agrupar comandos o usando sustitución de comandos. Con el fin
de evitar posibles efectos secundarios del script de arranque, las shells no-interactivas no leen
scripts de arranque tras el inicio.
Tras la salida, las shells de inicio de sesión leerán el archivo ~/.bash_logout si existe. En Red Hat
Enterprise Linux, el archivo simplemente ejecuta el comando clear para que la pantalla se limpie
de información tras la salida.
Ejemplos
El comando su revisitado
Con el fin de explorar las implicaciones de estos dos modos haremos que blondie agregue la
siguiente línea a su archivo ~/.bash_profile.
Del mismo
echo modo, agrega la siguiente
"~/.bash_profile línea a su archivo ~/.bashrc.
sourcing"
191
echo "~/.bashrc sourcing"
Ahora haremos que el usuario elvis haga su en blondie usando ambas formas.
En el primer caso, sólo el archivo ~/.bashrc fue leído. En el segundo caso, tanto ~/.bash_profile
como ~/.bashrc son leídos.
A menudo en este cuaderno y en las direcciones de Linux (y Unix), en general, se les pide a los
usuarios "salir e ingresar otra vez" para que los cambios de configuración surtan efecto. Esto suele
darse porque al instalar un nuevo software o algún otro cambio se han alterado los archivos de
configuración del usuario (o del sistema) bash y las direcciones desearían que el usuario reiniciara
la shell para que los archivos de arranque sean leídos otra vez.
A menudo, los usuarios pueden evitarlo releyendo los archivos clave de configuración en su lugar.
Por ejemplo, si blondie sospecha que un cambio ha ocurrido en el sistema de archivos de arranque
bash, podría leer de modo manual el archivo /etc/profile.
De otro modo, si blondie sospecha que sus archivos de arranque locales bash han cambiado,
entonces puede leer su archivo de configuración local bash manualmente.
(Observe que esto no funcionaría para todos los cambios de configuración, sino sólo para aquellos
relacionados con la shell bash. Por ejemplo, si una membresía de grupo de usuarios ha cambiado,
entonces el usuario sí tiene que salir e ingresar otra vez para que los cambios surtan efecto)
Ejercicios en línea Lab Exercise Objetivo: Configurar los scripts de arranque bashEstimated
Time: 10 mins.
Especificaciones
192
echo "sourcing ~/.bashrc"
rm -fr ~/.Trash/*
content_view let_
Deliverables A title Question 1
1. Una shell bash que tras el arranque de una shell de no-inicio de sesión emita el mensaje
sourcing ~/.bashrc
2. Una shell bash que tras el arranque de una shell de inicio de sesión emita los mensajes
sourcing ~/.bashrc y sourcing ~/.bash_profile.
3. Una shell bash que tras la salida de una shell de inicio de sesión suprima el contenido (no-
oculto) de la papelera de Nautilus.
193
Standar I/O and Pipes
Conceptos clave
• Los programas basados en la terminal tienden a leer información desde una fuente y a
escribir la información en un destino.
• La fuente desde donde se leen los programas se conoce como una entrada estándar
(stdin, del inglés standard in) y suele estar conectada al teclado de la terminal.
• El destino al que los programas escriben se conoce como una salida estándar (stdout, del
inglés standard out) y suele estar conectada a la pantalla de la terminal.
• Cuando se utiliza la shell bash, la stdout puede redirigirse mediante > o >> y la stdin puede
redirigirse mediante <.
Discussion
Muchos comandos de Linux leen la entrada desde el teclado y muestran la salida en la terminal. En
este cuaderno, aprenderá cómo se puede redirigir desde dónde se lee la entrada y a dónde va la
salida. La salida de un comando puede utilizarse como la entrada para otro comando, permitiendo
que los comandos sencillos se utilicen conjuntamente para realizar tareas más complejas.
En Linux (y Unix), los programas se pueden agrupar en los siguientes tres diseños.
Programas gráficos
Los programas gráficos están diseñados para ejecutarse en el entorno gráfico X. Esperan
que el usuario esté utilizando el ratón y los componentes gráficos comunes tales como
menús emergentes y botones para la entrada de parte del usuario. El navegador de red
mozilla es un ejemplo de un programa gráfico.
Programas de pantalla
Los programas de pantalla esperan utilizar una consola de texto. Hacen uso de toda la
pantalla y manejan la presentación del texto y rediseño de pantalla en formas sofisticadas.
No necesitan ratón y son apropiados para terminales y consolas virtuales. Los editores de
texto vi, nano y el navegador de red links son ejemplos de este tipo de programas.
Programas de terminal
Los programas de terminal reunen entradas y salidas de pantalla en un flujo, raras veces
rediseña la pantalla como si escribiese directamente a la impresora lo cual no permite al
cursor devolver la página. Debido a su sencillez, los programas basados en la terminal
suelen llamarse simplemente comandos. Ejemplos de este tipo de programas son ls, grep
y useradd.
194
Este capítulo se enfoca en este último tipo de programa. No permita que la simplicidad de estos
comandos que reciben entradas y salidas lo engañen. Usted hallará que muchos de estos
comandos son muy sofisticados y le permiten utilizar la interfaz de la línea de comandos de manera
eficaz.
Los programas de terminal suelen leer información como un flujo desde una sola fuente tal como el
teclado de una terminal. Igualmente, por lo general, escriben información como un flujo a un solo
destino como por ejemplo una pantalla. En Linux (y Unix), el flujo de entrada se conoce como
entrada estándar (suele abreviarse stdin) y el flujo de salida se conoce como salida estándar (o en
forma abreviada stdout).
Por lo general, stdin y stdout están conectadas a la terminal que ejecuta el comando. Algunas
veces para automatizar los comandos más repetidos, grabar la salida de un comando o incluirlo
más tarde en un informe o correo se considera conveniente redirigir stdin desde stdout hacia los
archivos.
Redirección de stdout
Cuando un programa de terminal genera salida, usualmente suele escribir esa salida a su flujo de
stdout, sin saber qué está conectado al final receptor de ese flujo. Con frecuencia el flujo de stdout
está conectado a la terminal que inició el proceso para que la salida sea escrita a la pantalla de la
terminal. La shell bash usa > para redirigir un flujo de stdout de proceso a un archivo.
Por ejemplo, suponga que la máquina que elvis está utilizando se vuelve muy lenta y no responde.
Con el fin de diagnosticar el problema, elvis desearía examinar los procesos que están
ejecutándose. Sin embargo, dado que la máquina es tan lenta, recoge información ahora pero la
analiza más tarde. Elvis puede redirigir la salida del comando ps aux al archivo sluggish.txt y
regresar para examinar el archivo cuando la máquina esté respondiendo mejor.
195
Agregando una salida a un archivo
Si el archivo sluggish.txt ya existió, su contenido original se perdería. Esto suele conocerse como
sobrescribir un archivo. Para agregar una salida de un comando a un archivo, en lugar de
sobrescribirlo, bash usa >>.
Suponga que elvis quiso registrar un marcador de tiempo de cuando se estaba presentando la
conducta lenta, como también una lista de los procesos actuales en ejecución. Primero podría
crear (o sobrescribir ) el archivo con la salida del comandodate mediante > y luego agregarlo a la
salida del comando ps aux mediante >>.
Redirección de stdin
Así como bash usa > para lograr que los comandos entreguen su salida en alguna otra parte que
no sea la pantalla, bash usa < para hacer que lean entradas desde alguna parte diferente al
teclado. El usuario elvis todavía está tratando de entender el porqué su máquina está lenta. Habla
con su administrador local de sistemas , quien piensa que examinar la lista de los procesos en
ejecución es una buena idea y le pide a elvis que le envíe una copia por correo.
Por medio del comando mail basado en la terminal, elvis escribe "manualmente" desde el teclado
un correo electrónico al administrador. El comando mail espera un destinatario como argumento y
la línea de asunto se puede especificar con la opción -s. El cuerpo del texto del correo electronico
se introduce luego desde el teclado. El final del texto se señala con un punto aparte en una línea.
Hey sysadmin...
I'm sending a list of processes that were running when the computer was running
in a separate email.
Thanks! --elvis
.
Cc:
196
Para su mensaje de seguimiento, elvis puede fácilmente enviar la salida del comando ps grabada
en el archivo sluggish.txt. Sólo redirige el flujo de stdin del comando mail para leerlo desde el
archivo.
El administrador de sistemas recibirá un correo electrónico de elvis con "salida ps" como su línea
de asunto y el contenido del archivo sluggish.txt como el cuerpo del texto.
En el primer caso, la stdin del proceso mail estaba conectada a la terminal y el cuerpo del mensaje
lo proporcionó el teclado. En el segundo caso, bash arregló para que la stdin del proceso mail se
conectara al archivo sluggish.txt y el cuerpo del mensaje fuera provisto por su contenido. El
comando mail no cambia su conducta básica. Este lee el cuerpo del mensaje desde stdin. [1]
Para apreciar plenamente cómo administrar procesos de entrada y salida estándar y archivos
debemos introducir el concepto de un descriptor de archivos. Con el fin de leer o escribir
información en un archivo un proceso debe abrir el archivo. Los procesos de Linux (y Unix)
mantienen el registro de los archivos que están abiertos mediante la asignación de un número
entero a cada uno. El número entero se conoce como un descriptor de archivos.
El kernel de Linux ofrece una forma fácil de examinar los archivos abiertos y los descriptores de
archivos de un proceso en ejecución mediante el sistema de archivos /proc. Cada proceso tiene un
subdirectorio asociado bajo /proc llamado como su PID (ID del proceso). El subdirectorio del
proceso a su vez tiene un subdirectorio llamado fd (del inglésfile descriptor). Dentro del
subdirectorio /proc/pid/fd, existe un enlace simbólico para cada archivo abierto por el proceso. El
nombre del enlace simbólico es el número entero del descriptor de archivo abierto y el enlace
simbólico apunta al archivo mismo.
A continuación, elvis ejecuta con cat el archivo /etc/termcap y luego casi de inmediato suspende el
programa con CONTROL-Z.
Usando el comando ps busca el PID del proceso, luego elvis examina el directorio del proceso
/proc/pid/fd.
197
[elvis@station elvis]$ ps
PID TTY TIME CMD
1368 pts/1 00:00:00 bash
1910 pts/1 00:00:00 cat
1911 pts/1 00:00:00 ps
[elvis@station elvis]$ ls -l /proc/1910/fd
total 0
lrwx------ 1 elvis elvis 64 Sep 13 06:42 0 -> /dev/tty1
lrwx------ 1 elvis elvis 64 Sep 13 06:42 1 -> /dev/tty1
lrwx------ 1 elvis elvis 64 Sep 13 06:42 2 -> /dev/tty1
lr-x------ 1 elvis elvis 64 Sep 13 06:42 3 -> /etc/termcap
No es de sorprender que el proceso cat tenga abierto el archivo /etc/termcap (debe poder leer el
archivo para mostrar su contenido). Quizás un poco extraño es que éste no esté sólo o incluso que
no sea el primer archivo abierto por el proceso. El comando cat tiene tres archivos abiertos antes
que éste o más exactamente, el mismo archivo abierto tres veces: /dev/tty1.
Como protocolo de Linux (y Unix), cada proceso hereda tres archivos abiertos tras el inicio. El
primero, el descriptor de archivo 0, es la entrada estándar. El segundo, el archivo descriptor 1, es la
salida estándar, y el tercero, el archivo descriptor 2, es el error estándar (será tratado en la
siguiente lección). ¿Qué archivos abiertos heredó el comando cat de la shell bash que lo inició? El
nodo del dispositivo /dev/tty1 para todos los tres.
Recuerde que /dev/tty1 es el nodo del dispositivo conectado al controlador dentro del kernel.
Cualquier cosa que elvis teclee se puede leer desde este archivo y cualquier cosa que se escriba
en este archivo aparecerá en la terminal de elvis. ¿Qué sucede si el proceso cat lee desde stdin?
Éste lee la entrada desde el teclado de elvis. ¿Qué sucede si éste escribe a stdout? Cualquier cosa
que se escriba se verá en la terminal de elvis.
Redirección
En el siguiente ejemplo, elvis ejecuta con cat el archivo /etc/termcap pero esta vez redirige stdout
al archivo /tmp/foo. Una vez más, elvis suspende el comando en la mitad del camino con las teclas
CONTROL-Z.
198
Utilizando la misma técnica anterior, elvis examina los archivos que el comando cat ha abierto y los
descriptores de archivo asociados con ellos.
[elvis@station elvis]$ ps
PID TTY TIME CMD
1368 pts/1 00:00:00 bash
1976 pts/1 00:00:00 cat
1977 pts/1 00:00:00 ps
[elvis@station elvis]$ ls -l /proc/1976/fd
total 0
lrwx------ 1 elvis elvis 64 Sep 13 07:05 0 -> /dev/pts/1
l-wx------ 1 elvis elvis 64 Sep 13 07:05 1 -> /tmp/foo
lrwx------ 1 elvis elvis 64 Sep 13 07:05 2 -> /dev/pts/1
lr-x------ 1 elvis elvis 64 Sep 13 07:05 3 -> /etc/termcap
Observe que el descriptor de archivo 1 (en otras palabras, la salida estándar) no está
conectado a la terminal sino al archivo /tmp/foo.
¿Qué sucede cuando elvis redirige tanto la entrada como la salida estándar?
Cuando el comando cat se llama sin argumentos (por ejemplo, sin ningún nombre de archivo o
archivos para mostrar), éste muestra la entrada estándar en su lugar. En lugar de abrir un archivo
específico (mediante el descriptor de archivo 3, como el anterior), el comando cat lee desde stdin.
No hay ninguna. Con el fin de apreciar el beneficio real del diseño de comandos para leer desde la
entrada estándar en lugar de los archivos llamados debemos esperar hasta que veamos las
tuberías en una próxima lección.
199
Ejemplos
Los siguientes ejemplos incluyen un ejemplo rápido de cómo los nuevos usuarios suelen
confundirse con comandos que leen desde la entrada estándar y un par de ejemplos de "la vida
real" que los programas ftp y gnuplot utilizan. Los programas ftp y gnuplot son complicados y
estos ejemplos apenas introducen algunas de sus funciones que sirven para hacer énfasis en uno
de los temas más importantes en este cuaderno: si el programa es conducido desde una interfaz
de línea de comandos, puede automatizarse con un script sencillo de texto y redirección.
A continuación, blondie emplea el comando sort para ordenar los animales que se encuentran en
el archivo de texto zoo.
Como el nombre en inglés lo indica, el comando sort (en su forma más simple) lee un archivo y
escribe línea por línea en orden alfabético. Al igual que el comando cat, cuando el comando sort
se ejecuta sin argumentos (por ejemplo, nombres de archivo para ordenar), esperará entradas
desde stdin.
Aunque esta conducta parece (y es) perfectamente razonable, a menudo confunde a los nuevos
usuarios quienes inocentemente teclean un nombre de comando, "sólo para ver qué hace". A
continuación, asuma que blondie no sabe aún sobre la entrada estándar. Al explorar, invoca el
comando sort. Sin entender que el comando sort está esperando para leer la entrada estándar,
por ejemplo, su teclado, trata de alguna manera de salir del comando que ha iniciado. Por último,
un amigo le dice en voz baja "CONTROL-D".
200
[blondie@station blondie]$ sort
ls
quit
man sort
exit
get me out of this
CTRL-D
exit
get me out of this
ls
man sort
quit
[blondie@station blondie]$
Tras teclear CONTROL-D, la secuencia de control convencional "Fin del archivo" (recuerde el
cuaderno 1), el comando sort imprime una lista ordenada de todo lo que se lee en la entrada
estándar.
La usuaria blondie usualmente toma un archivo README desde el servidor ftp para el proyecto del
kernel de Linux, ftp.kernel.org. El servidor kernel.org ftp permite usuarios anónimos, es decir,
usuarios que entran con el nombre de usuario "anónimo". Cuándo se les pide una contraseña, los
usuarios anónimos de ftp no necesitan entregar ninguna, pero por protocolo dan su dirección de
correo electrónico en su lugar.
201
[blondie@station student]$ ftp ftp.kernel.org
Connected to ftp.kernel.org (204.152.189.116).
220 ProFTPD [ftp.kernel.org]
Name (ftp.kernel.org:blondie): anonymous
331 Anonymous login ok, send your complete email address as your password.
Contraseña: (blondie teclea su dirección de correo-electrónico)
230 Anonymous access granted, restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (204,152,189,116,237,224).
150 Opening ASCII mode data connection for file list
drwxr-s--- 2 korg mirrors 4096 May 21 2001 for_mirrors_only
drwx------ 2 root root 16384 Mar 18 00:27 lost+found
drwxrwsr-x 8 korg korg 4096 Mar 24 17:46 pub
226 Transfer complete.
ftp> cd pub
250 CWD command successful.
ftp> ls
227 Entering Passive Mode (204,152,189,116,237,229).
g150 Opening ASCII mode data connection for file list
drwxrws--- 2 korg korg 4096 Mar 18 04:05 RCS
-r--r--r-- 1 korg korg 1963 Oct 4 2001 README
-r--r--r-- 1 korg korg 578 Mar 18 04:04 README_ABOUT_BZ2_FILES
drwxrwsr-x 4 korg korg 4096 Oct 26 2000 dist
...
226 Transfer complete.
ftp> get README
local: README remote: README
227 Entering Passive Mode (204,152,189,116,237,237).
150 Opening BINARY mode data connection for README (1963 bytes).
226 Transfer complete.
1963 bytes received in 0.000564 secs (3.4e+03 Kbytes/sec)
ftp> quit
221 Goodbye.
Cuando el comando ftp hace una pausa con el intérprete de comandosftp>, blondie teclea
comandos para navegar los directorios del servidor ftp. Si blondie descargara este archivo a
menudo, podría sentirse tentada a escribir un archivo de texto sencillo, getreadme.ftp, el cual
reproduciría los comandos tecleados por ella. Podría entonces ejecutar el mismo comando ftp
ftp.kernel.org. Sin embargo, esta vez usaría < para hacer que bash redirija stdin desde el archivo
getreadme.ftp. Cuando el comando ftp lee la entrada desde su flujo de stdin, la información es
provista por el archivo en lugar del teclado.
Primero, blondie utiliza un editor de texto sencillo para crear el archivo getreadme.ftp, el cual
contiene todos los comandos que ella escribió de modo interactivo en el teclado (incluyendo la
contraseña que dio al servidor anónimo ftp, [email protected]).
202
[blondie@station blondie]$ cat getreadme.ftp
anonymous
[email protected]
ls
cd pub
ls
get README
quit
Observe cómo el contenido del archivo coincide exactamente con lo que tecleó al utilizar el
comando anterior ftp. Luego, vuelve a ejecutar ftp ftp.kernel.org pero redirige stdin desde el
archivo recién creado.
Después de ejecutar el comando, blondie tiene un nuevo archivo README en su directorio, el cual
fue descargado por el comando ftp. Sin embargo, blondie tuvo un par de contratiempos.
• Primero, el comando se detuvo y ella tuvo pulsar una vez ENTER para que continuara. Por
razones de seguridad, muchos comandos, cuando leen contraseñas, no las leen desde
stdin, sino desde la terminal directamente, (los comandos no tienen que depender de stdin
como su único medio de entrada, aunque la mayoría lo hacen). Cuando ftp intentó leer la
contraseña desde la terminal, el programa se suspendió hasta que blondie pulsó la tecla
ENTER.
• Segundo, hay una línea rara que dice ?Invalid Input. Dado que la contraseña fue leída
directamente desde la terminal, no se infirió desde el archivo getreadme.ftp. Cuando el
comando ftp fue a leer la siguiente línea de la entrada decía [email protected], lo
que no reconoció como un comando.
• Por último, los listados de directorio fueron descargados en la terminal al ejecutar el
comando. Cuando el comando ftp ejecutó los comandos ls desde getreadme.txt, escribió
la salida en stdout, la cual está aún conectada a la terminal. Debido a que blondie sabe
dónde esta localizado el archivo y ha incluido esa información dentro de un script, no
necesita ver esos listados cada vez que ejecuta el comando.
Para resolver estos problemas, primero hace uso de un archivo~/.netrc. El comando ftp está
diseñado para buscar un archivo como ese en el directorio de inicio del usuario y si existe, éste
203
provee el nombre de usuario del usuario y la contraseña. Después de estudiar la página del manual
netrc(5), blondie usa un editor de texto sencillo para crear el siguiente archivo ~/.netrc.
Dado que el archivo ~/.netrc ahora provee su nombre de usuario y contraseña, blondie los suprime
de su script getreadme.ftp. Luego, quita los comandos innecesarios ls también desde el script.
Armada con su archivo ~/.netrc (para proveer su nombre de usuario y contraseña) y su archivo
getreadme.txt modificado (para proveer los comandos del programa ftp), vuelve a ejecutar el
comando ftp y la operación se realiza sin problemas.
Ella está interesada en las tres últimas columnas, las cuales son el porcentaje de tiempo que está
gastando la CPU en el sistema ("sy"), del usuario ("us") y en estado inactivo ("id"). Recopila 60
segundos de datos desde su máquina, la cual realiza muestreos cada segundo.
204
[madonna@station madonna]$ vmstat 1 60 > stats.txt
[madonna@station madonna]$ head stats.txt
procs memory swap io system cpu
r b swpd free buff cache si so bi bo in cs us sy id wa
2 6 0 17348 65604 277768 0 0 15 16 126 221 1 0 97 1
1 5 0 15736 66008 277788 0 0 376 6269 314 725 5 2 0 93
1 6 0 11496 67224 277392 0 0 1216 8 422 1533 15 16 0 69
0 6 0 10492 67944 277676 0 0 940 28 338 1193 7 8 0 85
0 6 0 10168 68324 277644 0 0 576 0 261 992 6 1 0 93
3 3 0 8848 69424 277864 0 0 1252 64 429 1386 10 16 0 74
3 3 0 8056 70188 277892 0 0 1068 1148 422 1215 8 16 0 76
1 6 0 12248 71084 277636 0 0 940 28 341 1275 9 4 0 87
Un poco frustrada porque las dos líneas de los encabezados interferirán con la diagramación de los
datos, madonna abre el archivo stats.txt en un editor de texto y los borra con facilidad.
Para diagramar los datos, utiliza gnuplot, un sofisticado paquete de diagramación, el cual usa
comandos leídos desde una interfaz de terminal para generar diagramas de funciones matemáticas
y datos numéricos. Después de navegar un poco a través de la ayuda en línea disponible dentro de
gnuplot desarrolla los siguientes comandos para diagramar sus datos como un archivo de gráficos
PNG llamado cpu.png.
G N U P L O T
Version 3.7 patchlevel 3
...
Después de salir de gnuplot vuelve a la shell bash, donde utiliza el visor de pantalla eog para ver
su diagrama.
205
Dado que madonna desearía a menudo generar un diagrama semejante, y no tener la angustia de
teclear el comando gnuplot a cada instante, genera un script que se puede utilizar para
automatizar gnuplot. Mediante un editor de texto, crea el archivo cpu_plot.gnuplot, el cual contiene
todos comandos gnuplot que entró desde el teclado, teniendo el cuidado de poner un comando
por línea.
Ahora puede diagramar con facilidad datos recopilados recientemente redirigiendo su script como
la stadin de gnuplot.
Ejercicios en línea
Uso de la entrada estándar y la salida estándar Lab Exercise Objetivo: Usar la redirección de la
shell bash para controlar de modo efectivo la entrada estándar y la salida estándar.Tiempo
estimado: 20 minutos.
Especificaciones
Si ha completado con éxito los tres pasos anteriores, usted debería poder reproducir una
salida semejante a la siguiente, (no se preocupe si la información difiere de la que se
muestra a continuación).
206
[student@station student]$ cat stdoutlab.txt
station
07:09:31 up 11:30, 5 users, load average: 0.19, 0.06, 0.01
Linux station 2.4.20-20.9 #1 Mon Aug 18 11:45:58 EDT 2003 i686 i686 i386
GNU/Linux
4. Genere un archivo de texto sencillo, ~/script.gnuplot, el cual sirva de script para controlar
gnuplot. Cuando gnuplot lea su script desde stdin, debería generar un diagrama de una
expresión matemática simple tal como el seno de x (sin(x)) o x al cuadrado (x**2). El
diagrama debería generarse como un gráfico PNG llamado "gnuplot.png".
Una vez completado su script debería poderse utilizar como en el próximo ejemplo.
Utilizando el ejemplo 3 como su guía, experimente de modo interactivo con gnuplot, hasta que
pueda generar un diagrama sencillo. Si está utilizando una terminal de texto de un entorno gráfico
X puede generar diagramas de texto al establecer su terminal de salida gnuplot como terminal
"tonta":
[student@station student]$ ls
script.gnuplot
[student@station student]$ gnuplot < script.gnuplot
[student@station student]$ ls
gnuplot.png script.gnuplot
[student@station student]$ file gnuplot.png
gnuplot.png: PNG image data, 640 x 480, 8-bit colormap, non-interlaced
[student@station student]$ eog gnuplot.png
Una vez que pueda producir gráficos, establezca su tipo de terminal a png (para gráficos PNG) y su
archivo de salida en "gnuplot.png" mediante los siguientes comandos ...
... y genere su diagrama una vez más. Cuando haya entendido la secuencia de comandos para
generar un diagrama como un archivo PNG registre los comandos como su script gnuplot.
207
Error estándar
Conceptos clave
• Los programas Unix reportan condiciones de error a un destino llamado error estándar
(stderr).
• Usualmente, stderr está conectado a una pantalla de terminal y los mensajes de error se
encuentran entremezclados con las salidas estándar.
• Cuando se utiliza la shell bash, el flujo de stderr puede redirigirse a un archivo mediante
2>.
• Al utilizar bash, el flujo de stderr puede combinarse con el flujo de stdout mediante 2>&1 o
>&
Discussion
Hemos discutido los flujos de salida y de entrada estándar, stdin y stdout y cómo usar > y < en la
línea de comandosbash para redirigirlos. Ahora estamos listos para complicar un poco las cosas
introduciendo un segundo flujo de salida, muy usado para reportar condiciones de error, llamado
error estándar (a menudo abreviado stderr).
En la siguiente secuencia, elvis está utilizando el comando head -1 para generar una lista de las
primeras líneas de todos los archivos en el directorio /etc/rc.d.
208
[elvis@station elvis]$ ls -F /etc/rc.d/
init.d/ rc0.d/ rc2.d/ rc4.d/ rc6.d/ rc.sysinit*
rc* rc1.d/ rc3.d/ rc5.d/ rc.local* rc.sysinit.rpmsave*
[elvis@station elvis]$ head -1 /etc/rc.d/*
==> /etc/rc.d/init.d <==
head: /etc/rc.d/init.d: Is a directory
==> /etc/rc.d/rc <==
#! /bin/bash
==> /etc/rc.d/rc0.d <==
head: /etc/rc.d/rc0.d: Is a directory
==> /etc/rc.d/rc1.d <==
head: /etc/rc.d/rc1.d: Is a directory
==> /etc/rc.d/rc2.d <==
head: /etc/rc.d/rc2.d: Is a directory
==> /etc/rc.d/rc3.d <==
head: /etc/rc.d/rc3.d: Is a directory
==> /etc/rc.d/rc4.d <==
head: /etc/rc.d/rc4.d: Is a directory
==> /etc/rc.d/rc5.d <==
head: /etc/rc.d/rc5.d: Is a directory
==> /etc/rc.d/rc6.d <==
head: /etc/rc.d/rc6.d: Is a directory
==> /etc/rc.d/rc.local <==
#!/bin/sh
==> /etc/rc.d/rc.sysinit <==
#!/bin/bash
==> /etc/rc.d/rc.sysinit.rpmsave <==
#!/bin/bash
Cuando se alimenta el comando head con múltiples archivos como argumentos este representa de
manera conveniente el nombre del archivo, seguido por el primer número especificado de las
líneas (en este caso, uno). Sin embargo, cuando el comando head encuentra un directorio apenas
se queja. Luego, elvis ejecuta el mismo comando, redirigiendo stdout al archivorcsummary.out.
La mayor parte de la salida es obedientemente redirigida al archivo rcsummary.out, pero las quejas
del directorio aún se visualizan. Aunque no es obvio desde el principio, el comando head está
realmente enviando salida a dos flujos independientes. La salida normal se escribe en la salida
estándar, pero un mensaje de error se escribe en un flujo separado llamado error estándar (a
menudo abreviado stderr). Ambos flujos suelen estar conectados a la terminal y por eso es difícil
distinguirlos. No obstante, al redireccionar stdout, la información escrita a stderr es evidente.
Redirección de stderr
209
Así como bash usa > para redirigir lastdout, bash usa 2> para redirigir elstderr. Por ejemplo, elvis
repite el comando head desde arriba, pero en vez de redirigir stdout a rcsummary.out, redirige el
stderr al archivo rcsummary.err.
La mayor parte de la salida es obedientemente redirigida al archivo rcsummary.out, pero las quejas
del directorio aún se visualizan. Aunque no es obvio desde el principio, el comando head está
realmente enviando salida a dos flujos independientes. La salida normal se escribe en la salida
estándar, pero un mensaje de error se escribe en un flujo separado llamado error estándar (a
menudo abreviado stderr). Ambos flujos suelen estar conectados a la terminal y por eso es difícil
distinguirlos. No obstante, al redireccionar stdout, la información escrita a stderr es evidente.
Redirección de stderr
Así como bash usa > para redirigir lastdout, bash usa 2> para redirigir elstderr. Por ejemplo, elvis
repite el comando head desde arriba, pero en vez de redirigir stdout a rcsummary.out, redirige el
stderr al archivo rcsummary.err.
210
La salida es el complemento al ejemplo anterior. Ahora vemos la salida normal visualizada en la
pantalla, pero sin mensajes de error. ¿A dónde fueron a parar los mensajes de error? No costaría
mucho trabajo adivinar.
En el siguiente ejemplo tanto > como 2> se utilizan para redirigir stdout y stderr de modo
independiente.
Con frecuencia, desearíamos redirigir los flujos de stdout y stderr combinados en un sólo archivo.
Como un primer intento, elvis ensaya el siguiente comando.
Sin embargo, tras examinar el archivo rcsummary.both, elvis no halla lo que espera.
211
La shell bash abrió dos veces el archivo rcsummary.both, pero trató cada archivo abierto como un
archivo independiente. Cuando stdout y stderr escribieron al archivo, sobrescribieron la información
de cada cual. Lo que se necesitaba en su lugar es de alguna manera pedirle a bash combinar de
modo eficaz stderr y stdout dentro de un sólo flujo y luego redirigir ese flujo a un archivo único.
Como es de esperarse, esa forma existe.
Aunque un poco extraño, el último símbolo 2>&1 debería considerarse como si se dijera "tome al
stderr, y envíelo a dónde stdout está actualmente". Ahora,rcsummary.both contiene la salida
esperada.
Al usar 2>&1 para combinar stdout y stderr se introdujo en la shell Unix original, la shell Bourne
(sh). Dado que bash está diseñado para ser compatible con sintaxis anteriores sh también soporta
esta sintaxis. Sin embargo, la sintaxis no es conveniente. Además de ser difícil de escribir, el orden
de las redirecciones es importante. Al usar ">out.txt 2>&1" y "2>&1 >out.txt" ¡no produce el
mismo efecto!
Para simplificar las cosas, bash usa >& para combinar stdin y stdout como en el siguiente ejemplo.
Resumen
El siguiente cuadro resume la sintaxis empleada por la shell bash para redireccionar stdin, stdout,
y stderr tratados en la lección anterior y en ésta.
sintaxis efecto
cmd < file Redirección stdin desde file
cmd > file Redirigir stdout a file, sobrescribir file si existe.
cmd >> file Redirigir stdout a file agregando file si existe.
212
cmd 2> file Redirigir stderr a file sobrescribir file si existe.
cmd 2>> file Redirigir stderr a file agregando file si éste existe.
cmd > file 2>&1 Combinar stdout y stderr, y redirigirlos a file. (sintaxis portátil)
cmd >& file Combinar stdout y stderr y redirigirlos a file.(sintaxis conveniente)
Ejemplos
El usuario elvis recientemente ha aprendido que aparte de los directorios /home/elvis y /tmp con los
que está familiarizado, también puede tener archivos en el directorio /var. Estos archivos en espera
suelen ser archivos para correos electrónicos recibidos, pero que no han sido vistos, o por ejemplo,
también pueden ser trabajos de impresión en espera.
Intrigado usa el comando find para buscar todos los archivos dentro del directorio /var que posee.
Aunque esto funciona, elvis queda con un archivo llamado /tmp/foo que en realidad no quería. En
situaciones como ésta, cuando un usuario quiere deshacerse de un flujo de información, los
usuarios experimentados de Unix suelen redirigir la salida a un seudo dispositivo llamado /dev/null.
213
Como lo muestra el siguiente listado largo, /dev/null es un nodo de dispositivo de caracter como
aquellos de los controladores de dispositivo convencionales.
Cuando un usuario escribe en /dev/null, la información es apenas descartada por el kernel. Cuando
un usuario lee desde /dev/null encuentra inmediatamente un fin de archivo. Observe que /dev/null
es uno de los pocos archivos en Red Hat Enterprise Linux que tiene permisos de escritura por
defecto para todo el mundo.
Ejercicios en línea Lab Exercise Objetivo: Administrar de modo efectivo los flujos de la entrada
estándar, la salida estándar y el error estándar Estimated Time: 10 mins.
Especificaciones
1. Utilice la siguiente línea de comandos para mostrar el contenido de todos los archivos
dentro del directorio /etc/X11.
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
...
1. Un archivo llamado ~/stderrlab.out que contenga el flujo de stdout desde el comando cat
/etc/X11/*.
2. Un archivo llamado ~/stderrlab.err que contenga el flujo de stderr desde el comando cat
/etc/X11/*.
3. Un archivo llamado ~/stderrlab.both que contenga los flujos stdout y stderr combinados
desde el comando cat /etc/X11/*.
214
Tuberías
Conceptos clave
• El flujo de stdout desde un proceso puede estar conectado al flujo de stdin de otro proceso
mediante lo que Unix llama una "tubería".
• Varios de los comandos en Unix están diseñados para operar como un filtro, leer la entrada
desde stdin y enviar la salida a stdout.
• bash usa "|" para crear una tubería entre dos comandos.
Discussion
Tuberías
En las lecciones anteriores, hemos visto que una salida de un proceso se puede redirigir a
cualquier parte con excepción de la pantalla de la terminal o que puede pedírsele a un proceso que
lea desde alguna parte con excepción del teclado de la terminal. Una de las formas más comunes y
eficaces para redirigir es una combinación de las dos, donde la salida (salida estándar) de un
comando es "entubada" directamente dentro de la entrada (entrada estándar) de otro comando
formando lo que Linux (y Unix) llaman tubería.
Cuando dos comandos se unen por medio de una tubería, el flujo de stdout del primer proceso es
ligado directamente a la secuencia stdin del segundo proceso para que múltiples procesos puedan
combinarse en una secuencia. Con el fin de crear unq tubería por medio de bash, los dos
comandos se unen con una barra vertical |, (en la mayoría de los teclados este caracter está en la
misma tecla de una barra invertida encima de ENTER). A todos los procesos unidos en una tubería
se les llama un grupo de proceso.
A manera de ejemplo, piense que prince está tratando de hallar los archivos más grandes bajo el
directorio /etc. Comienza por escribir el comando find para obtener un listado de archivos con un
tamaño mayor a 100kbytes.
Al observar que el comando find no parece listar los archivos en ningún orden en particular, prince
decide que sus archivos sean listados en orden alfabético. En lugar de redirigir la salida a un
archivo y luego sort el archivo, aprovecha que el comando sortse invoca sin argumentos y espera
los datos desde la entrada estándar para ordenarlos. Él entuba la salida de su comando de
búsqueda hacia sort.
215
[prince@station prince]$ find /etc -size +100k 2>/dev/null | sort
/etc/aep/aeptarg.bin
/etc/gconf/gconf.xml.defaults/schemas/apps/gedit-2/preferences/editor/save/
%gconf.xml
/etc/gconf/gconf.xml.defaults/schemas/apps/gnomemeeting/general/%gconf.xml
...
/etc/makedev.d/cciss
/etc/makedev.d/dac960
/etc/squid/squid.conf
/etc/squid/squid.conf.default
/etc/termcap
El comando tradicional de Unix grep se utiliza en tuberías para reducir datos a sólo las partes
"interesantes". El comando grep se analizará más tarde en un cuaderno. Aquí presentamos el
comando grep en su forma más sencilla.
El comando grep se utiliza para buscar y extraer líneas que contengan una cadena de texto
específico. Por ejemplo, a continuación, prince imprime todas las líneas que contienen el texto
"root" desde el archivo /etc/passwd.
El primer argumento para el comando grep es la cadena de texto que va a ser buscada, y los
argumentos restantes son archivos que van a ser buscados para el texto. Si el comando grep
llamado con un solo argumento (una cadena de texto para ser buscada, pero no archivos), espera
la entrada estándar como su fuente de información en la cual operar.
En el siguiente, prince tiene tantos archivos en su directorio de inicio que está teniendo problemas
para seguirles el rastro. Trata de hallar un directorio llamadotemplates que él creó hace unos
meses. Utiliza el comando locate para encontrarlo.
216
Por desgracia para prince, hay muchos archivos en el sistema que contienen el textotemplates en
su nombre y se confunde con líneas y líneas de salida. Con el fin de reducir la información a
archivos más importantes, prince toma la stdout desde el comando locate y crea una tubería para
la stdin del comandogrep, "buscando" la palabra "prince".
Dado que al comando grep no se le da un archivo para buscar, espera a la stdin, donde encuentra
el flujo de stdout del comando locate. Al filtrar el flujo, grep sólo duplica a sus líneas stdout que
coincidieron con el texto especificado, "prince". El resto fue descartado. El usuario prince encuentra
fácilmente su directorio bajo ~/proj, como también otro directorio creado por la aplicación quanta.
Tuberías y stderr
En el próximo ejemplo, prince quiere ver dónde aparece en los archivos de configuración del
sistema y utiliza la herramienta "grep" con su nombre en el directorio /etc.
De nuevo, prince está abrumado con tanta salida desde este comando. Emplea el mismo truco de
buscar con "grep" todas las líneas que contengan la palabra "passwd".
217
[prince@station prince]$ grep prince /etc/* | grep passwd
grep: /etc/aliases.db: Permission denied
grep: /etc/at.deny: Permission denied
grep: /etc/default: Permission denied
grep: /etc/group-: Permission denied
grep: /etc/group.lock: Permission denied
...
grep: /etc/lvmtab: Permission denied
/etc/passwd:prince:x:502:502::/home/prince:/bin/bash
grep: /etc/passwd-: Permission denied
grep: /etc/passwd.lock: Permission denied
...
Aunque stdout desde el primer comando con grep fue filtrado correctamente, stderr no se afectó y
aún se muestra en la pantalla. ¿Cómo le iría a prince si suprimiera también stderr?
El concepto de tubería se extiende naturalmente para que múltiples comandos se puedan usar en
conjunto, cada información de lectura desde stdin, de alguna manera modifica o filtra la información
y pasa el resultado a stdout. En un próximo cuaderno, usted verá que hay muchos comandos
estándar de Linux (y Unix) diseñados para este propósito, incluyendo algunos de los cuales usted
ya conoce: grep, head, tail, cut, sort, sed, y awk por nombrar unos cuantos.
Ejemplos
A menudo, quisiéramos listar información acerca de procesos que están ejecutando un comando
específico. Aunque ps aux presenta un montón de información sobre procesos actuales en
ejecución, el número de procesos ejecutándose en la máquina puede resultar en una la salida
abrumadora. El comando grep puede ayudar a simplificar la salida.
A continuación, prince quiere listar información sobre los procesos que están implementando su
servidor de red, el comando httpd. Él lista todos los procesos pero luego reduce la salida a solo
aquellas líneas que contengan el texto httpd.
218
Recientemente, el usuario prince tomó un buen tiempo construyendo una línea de comandos find,
la cual listaba todos los archivos grandes bajo el directorio /etc, incluyendo el tamaño. En lugar de
repetir su esfuerzo prefiere ver si el comando está aún en su historial. Dado que su historial
contiene cientos de líneas, utiliza el comando grep para ayudar a reducir la salida.
Ahora localiza la línea de comandos que quería y utiliza la sustitución del historial para repetir el
comando con facilidad.
Linux, al igual que Unix, se basa fundamentalmente en la filosofía de que los sistemas complejos
deberían crearse de componentes simples y de componentes especializados que funcionen
fácilmente entre sí. Siguiendo esta filosofía, muchos programas estándar de Linux están diseñados
para operar como filtros, leyendo información desde una fuente estándar manipulando los datos y
entregando el resultado a un destino estándar.
Esta filosofía es importante para ilustrar el uso de un ejemplo largo y detallado. El ejemplo utilizará
comandos con los que usted aún no está familiarizado. No se preocupe de los detalles de cómo
usar los comandos, en su lugar, enfóquese en cómo funcionan juntos, cada comando realiza un
pequeña parte para producir el resultado deseado.
Suponga que un administrador de sistemas está examinando los mensajes de alquiler DHCP en un
archivo de registro bien conocido, /var/log/messages. Si usted no está familiarizado con DHCP, es
el protocolo por medio del cual las direcciones IP se pueden asignar a máquinas basadas en la
dirección de hardware (MAC) construídas dentro de una tarjeta de Ethernet de la máquina. En las
siguientes líneas de /var/log/messages enfóquese en la línea que contiene la palabra
DHCPOFFER. Observe que la dirección IP 192.168.0.11 se está ofreciendo a la tarjeta de Ethernet
con la dirección de hardware de 00:08:74:37:c5:c3.
219
...
May 27 12:18:21 server1 dhcpd: DHCPACK on 192.168.0.110 to 00:09:6b:d0:ce:8f via eth0
May 27 12:18:27 server1 login(pam_unix)[1981]: session closed for user root
May 27 12:19:15 server1 named[24350]: listening on IPv4 interface eth1,
192.168.22.20#53
May 27 12:19:21 server1 vsftpd: warning: can't get client address: Bad file
descriptor
May 27 12:19:21 server1 last message repeated 3 times
May 27 12:20:27 server1 dhcpd: DHCPDISCOVER from 00:08:74:37:c5:c3 via eth0
May 27 12:20:27 server1 dhcpd: DHCPOFFER on 192.168.0.11 to 00:08:74:37:c5:c3 via
eth0
May 27 12:20:27 server1 dhcpd: DHCPREQUEST for 192.168.0.11 (192.168.0.254) from
00:08:74:37:c5:c3 via eth0
...
Sin preocuparse por detalles del protocolo de DHCP, suponga que el administrador deseara
extraer una lista de direcciones IP y las direcciones de hardware que se ofrecen en el archivo de
registro. Un administrador experimentado podría emplear el siguiente método.
Dándose cuenta que el archivo /var/log/message es un archivo muy grande, en este caso más de
1000 líneas de longitud, el administrador primero utiliza el comando grep para reducir la
información a las líneas pertinentes.
Este es un comienzo pero el administrador aún está manejando demasiada información (la toma de
pantalla de arriba sólo lista las primeras 5 de 90 líneas producidas por este comando). Con el fin de
extraer sólo la información pertinente, es decirla dirección IP y la dirección de hardware, el
administrador toma la salida del comando grep y la entuba a un comando llamado sed, el cual
quita las primeras palabras de cada línea.
220
Si no está familiarizado con el comando sed (muy probablemente no lo está), no se preocupe por
los detalles, sólo observe que el argumento de sed quitó el texto inicial de cada línea hasta la
palabra "on". Como no queda mucho texto, el administrador toma la salida de esta combinación
grep-sed y la entuba al comando llamado awk.
De nuevo, no se preocupe por los detalles del comando awk, observe que el resultado era extraer
la primera y tercera columna de la salida anterior. Con el fin de ordenar la información, y quitar las
líneas que se duplican, el administrador toma la salida desde la cadena y la entuba a través de los
comandos sort y uniq.
221
[root@station log]$ grep DHCPOFFER messages | sed "s/^.*on //" | awk '{print $1,
$3}' | sort -n -k4 -t. | uniq
192.168.0.1 00:08:74:d9:41:9e
192.168.0.2 00:08:74:d9:41:32
192.168.0.3 00:08:74:d9:40:a4
192.168.0.4 00:08:74:d9:3f:7f
192.168.0.5 00:08:74:34:fd:36
192.168.0.6 00:08:74:d9:41:a3
192.168.0.7 00:08:74:d9:41:53
192.168.0.8 00:08:74:d9:41:7b
192.168.0.9 00:08:74:35:00:1f
192.168.0.10 00:08:74:d9:40:95
192.168.0.11 00:08:74:37:c5:c3
192.168.0.12 00:08:74:d9:41:dd
192.168.0.13 00:08:74:35:00:d0
192.168.0.14 00:08:74:34:fe:bc
192.168.0.15 00:08:74:37:c8:eb
192.168.0.16 00:08:74:d9:41:ac
192.168.0.17 00:08:74:35:00:e3
192.168.0.110 00:09:6b:d0:ce:8f
Esta es la lista que el administrador quería, en el orden deseado. Redirige todo esta salida a un
archivo en su directorio de inicio.
[root@station log]$ grep DHCPOFFER messages | sed "s/^.*on //" | awk '{print $1
,$3}' | sort -n -k4 -t. | uniq > ~/ip_dhcp.txt
Si el administrador utilizara un sistema operativo que no estuviera diseñado en torno a esta filosofía
de "pequeñas herramientas que trabajan juntas", habría necesitado depender de algún
programador para desarrollar la utilidad ip_mac_extractor y posiblemente depender de ese
programador para crear también una interfaz gráfica de usuario. En cambio, como pudo utilizar la
flexibilidad de la línea de comando, pudo también manejar la información por sí mismo.
Ejercicios en línea Lab Exercise Objetivo: Usar tuberías para filtrar información de modo
efectivo.Estimated Time: 10 mins.
Especificaciones
1. Usted desearía crear una lista ordenada de todos los servicios de TCP services que se
encuentran en el archivo /etc/services. Entube la salida del comandogrep tcp
/etc/services dentro del comando sort. Redirija la salida de esta tubería dentro del archivo
~/pipelab.txt.
2. Mediante el visualizador de página less desearía navegar la salida del comando ls -R /,
viendo sólo archivos que contengan la letra s. Escriba un línea de comando con dos
222
tuberías para encadenar los comandos ls -R /, grep s, y less. Abandone el visualizador de
página less en el primer plano mientras califica su ejercicio.
1. Un archivo ~/pipelab.txt que contenga la salida del comando grep tcp /etc/services
entubado a través del comando sort. Final del formulario
Limpieza
223
String Processing Tools
Conceptos clave
• When storing text, computers transform characters into a numeric representation. This
process is referred to as encoding the text.
• In order to accommodate the demands of a variety of languages, several different encoding
techniques have been developed. These techniques are represented by a variety of
character sets.
• La técnica de codificación más prevalente y antigua se conoce como el conjunto de
caracteres ASCII, el cual sirve aún como el denominador menos común entre otras
técnicas.
• El comando wc cuenta el número de caracteres, palabras y líneas en un archivo. Cuando
se aplica a datos estructurados, el comando wc puede convertirse en una herramienta
versátil de conteo.
• El comando cat tiene opciones que permiten la representación de caracteres de no
impresión tal como el caracter NEWLINE.
• Los comandos head y tail tienen opciones que le permiten imprimir sólo un cierto número
de líneas o un cierto número de bytes de un archivo, (un byte suele correlacionarse con un
caracter).
Discussion
Archivos
Linux, like most operating systems, stores information that needs to be preserved outside of the
context of any individual process in files. (In this context, and for most of this Workbook, the term
file is meant in the sense of regular file). Linux (and Unix) files store information using a simple
model: information is stored as a single, ordered array of bytes, starting from at first and ending at
the last. The number of bytes in the array is the length of the file. [1]
What type of information is stored in files? Here are but a few examples.
• The characters that compose the book report you want to store until you can come back
and finish it tomorrow are stored in a file called (say) ~/bookreport.txt.
• The individual colors that make up the picture you took with your digital camera are stored
in the file (say) /mnt/camera/dcim/100nikon/dscn1203.jpg.
224
• The characters which define the usernames of users on a Linux system (and their home
directories, etc.) are stored in the file /etc/passwd.
• The specific instructions which tell an x86 compatible CPU how to use the Linux kernel to
list the files in a given directory are stored in the file /bin/ls.
What is a Byte?
At the lowest level, computers can only answer one type of question: is it on or off? What is it?
When dealing with disks, it is a magnetic domain which is oriented up or down. When dealing with
memory chips, it is a transistor which either has current or doesn't. Both of these are too difficult to
mentally picture, so we will speak in terms of light switches that can either be on or off. To your
computer, the contents of your file is reduced to what can be thought of as an array of (perhaps
millions of) light switches. Each light switch can be used to store one bit of information (is it on, or is
it off).
Using a single light switch, you cannot store much information. To be more useful, an early
convention was established: group the light switches into bunches of 8. Each series of 8 light
switches (or magnetic domains, or transistors, ...) is a byte. More formally, a byte consists of 8 bits.
Each permutation of ons and offs for a group of 8 switches can be assigned a number. All switches
off, we'll assign 0. Only the first switch on, we'll assign 1; only the second switch on, 2; the first and
second switch on, 3; and so on. How many numbers will it take to label each possible permutation
for 8 light switches? A mathematician will quickly tell you the answer is 2^8, or 256. After grouping
the light switches into groups of eight, your computer views the contents of your file as an array of
bytes, each with a value ranging from 0 to 255.
Data Encoding
In order to store information as a series of bytes, the information must be somehow converted into a
series of values ranging from 0 to 255. Converting information into such a format is called data
encoding. What's the best way to do it? There is no single best way that works for all situations.
Developing the right technique to encode data, which balances the goals of simplicity, efficiency (in
terms of CPU performance and on disk storage), resilience to corruption, etc., is much of the art of
computer science.
As one example, consider the picture taken by a digital camera mentioned above. One encoding
technique would divide the picture into pixels (dots), and for each pixel, record three bytes of
information: the pixel's "redness", "greenness", and "blueness", each on a scale of 0 to 255. The
first three bytes of the file would record the information for the first pixel, the second three bytes the
second pixel, and so on. A picture format known as "PNM" does just this (plus some header
information, such as how many pixels are in a row). Many other encoding techniques for images
exist, some just as simple, many much more complex.
Codificación de texto
Perhaps the most common type of data which computers are asked to store is text. As computers
have developed, a variety of techniques for encoding text have been developed, from the simple in
concept (which could encode only the Latin alphabet used in Western languages) to complicated
but powerful techniques that attempt to encode all forms of human written communication, even
attempting to include historical languages such as Egyptian hieroglyphics. The following sections
discuss many of the encoding techniques commonly used in Red Hat Enterprise Linux.
ASCII
225
One of the oldest, and still most commonly used techniques for encoding text is called ASCII
encoding. ASCII encoding simply takes the 26 lowercase and 26 uppercase letters which compose
the Latin alphabet, 10 digits, and common English punctuation characters (those found on a
keyboard), and maps them to an integer between 0 and 255, as outlined in the following table.
What about the integers 0 - 32? These integers are mapped to special keys on early teletypes,
many of which have to do with manipulating the spacing on the page being typed on. The following
characters are commonly called "whitespace" characters.
Others of the first 32 integers are mapped to keys which did not directly influence the "printed
page", but instead sent "out of band" control signals between two teletypes. Many of these control
signals have special interpretations within Linux (and Unix).
226
What about the values 128-255? ASCII encoding does not use them. The ASCII standard only
defines the first 128 values of a byte, leaving the remaining 128 values to be defined by other
schemes.
Other standard encoding schemes have been developed, which map various glyphs (such as the
symbol for the Yen and Euro), diacritical marks found in many European languages, and non Latin
alphabets to the latter 128 values of a byte which the ASCII standard leaves undefined. The
following table lists a few of these standard encoding schemes, which are referred to as character
sets. The following table lists some character sets which are supported in Linux, including their
informal name, formal name, and a brief description.
All of these character encoding schemes use a common technique. They preserve the first 128
values of a byte to encode traditional ASCII, and use the remaining 128 values to encode glyphs
unique to the particular encoding. For example, ISO 8859-1 (Latin-1) uses the value 196 to encode
a Latin capital A with an umlaut (), while ISO-8859-7 (Greek) uses the value 196 to encode the
Greek capital letter Delta (), but both use the value 101 to encode a Latin lowercase e.
1. Each of the alternate encodings map a single glyph to a single byte, so that the number of
letters encoded in a file equals the number of bytes which are required to encode them.
2. Choosing a particular character set extends the range of characters that can be encoded,
but you cannot encode characters from different character sets simultaneously. For
example, you could not encode both a Latin capital A with a grave and a Greek letter Delta
simultaneously.
Unicode (UCS)
In order to overcome the limitations of ASCII and ISO 8859 based encoding techniques, a Universal
Character Set has been developed, commonly referred to as UCS, or Unicode. The Unicode
standard acknowledges the fact that one byte of information, with its ability to encode 256 different
values, is simply not enough to encode the variety of glyphs found in human communication.
Instead, the Unicode standard uses 4 bytes to encode each character. Think of 4 bytes as 32 light
switches. If we were to again label each permutation of on and off for 32 switches with integers, the
mathematician would tell you that you would need 4,294,967,296 (over 4 billion) integers. Thus,
Unicode can encode over 4 billion glyphs (nearly enough for every person on the earth to have their
own unique glyph; the user prince would approve).
Scale
227
The Unicode standard will easily be able to encode the variety of glyphs used in human
communication for a long time to come.
Simplicidad
The Unicode standard does have the simplicity of a sledgehammer. The number of bytes
required to encode a set of characters is simply the number of characters multiplied by 4.
Desperdicio
While the Unicode standard is simple in concept, it is also very wasteful. The ability to
encode 4 billion glyphs is nice, but in reality, much of the communication that occurs today
uses less than a few hundred glyphs. Of the 32 bits (light switches) used to encode each
character, the first 20 or so would always be "off".
ASCII Non-compatibility
For better or for worse, a huge amount of existing data is already ASCII encoded. In order
to convert fully to Unicode, that data, and the programs that expect to read it, would have to
be converted.
The Unicode standard is an effective standard in principle, but in many respects it is ahead of its
time, and perhaps forever will be. In practice, other techniques have been developed which attempt
to preserve the scale and versatility of Unicode, while minimizing waste and maintaining ASCII
compatibility. What must be sacrificed? Simplicity.
UTF-8 encoding attempts to balance the flexibility of Unicode, and the practicality and
pervasiveness of ASCII, with a significant sacrifice: variable length encoding. With variable length
encoding, each character is no longer encoded using simply 1 byte, or simply 4 bytes. Instead, the
traditional 127 ASCII characters are encoded using 1 byte (and, in fact, are identical to the existing
ASCII standard). The next most commonly used 2000 or so characters are encoded using two
bytes. The next 63000 or so characters are encoded using three bytes, and the more esoteric
characters may be encoded using from four to six bytes. Details of the encoding technique can be
found in the utf-8(7) man page. With full backwards compatibility to ASCII, and the same functional
range of pure Unicode, what is there to lose? ISO 8859 (and similar) character set compatibility.
UTF-8 attempts to bridge the gap between ASCII, which can be viewed as the primitive days of text
encoding, and Unicode, which can be viewed as the utopia to aspire toward. Unfortunately, the
"intermediate" methods, the ISO 8859 and other alternate character sets, are as incompatible with
UTF-8 as they are with each other.
Additionally, the simple relationship between the number of characters that are being stored and the
amount of space (measured in bytes) it takes to store them is lost. How much space will it take to
store 879 printed characters? If they are pure ASCII, the answer is 879. If they are Greek or Cyrillic,
the answer is closer to twice that much.
In the traditional development of operating systems, decisions such as what type of character
encoding to use can be made centrally, with the possible disadvantage that the decision is wrong
for some community of the operating system's users. In contrast, in the open source development
228
model, these types of decisions are generally made by individuals and small groups of contributers.
The advantages of the open source model are a flexible system which can accommodate a wide
variety of encoding formats. The disadvantage is that users must often be educated and made
aware of the issues involved with character encoding, because some parts of the assembled
system use one technique while others parts use another. The library of man pages is an excellent
example.
When contributors to the open source community are faced with decisions involving potentially
incompatible formats, they generally balance local needs with an appreciation for adhering to widely
accepted standards where appropriate. The UTF-8 encoding format seems to be evolving as an
accepted standard, and in recent releases has become the default for Red Hat Enterprise Linux.
The following paragraph, extracted from the utf-8(7) man page, says it well:
Internacionalización (i18n)
As this Workbook continues to discuss many tools and techniques for searching, sorting, and
manipulating text, the topic of internationalization cannot be avoided. In the open source
community, internationalization is often abbreviated as i18n, a shorthand for saying "i-n with 18
letters in between". Applications which have been internationalized take into account different
languages. In the Linux (and Unix) community, most applications look for the LANG environment
variable to determine which language to use.
At the simplest, this implies that programs will emit messages in the user's native language.
The LANG environment variable is used to define a user's language, and possibly the default
encoding technique as well. The variable is expected to be set to a string using the following syntax:
LL_CC.enc
229
The variable context consists of the following three components.
Componente Función
LL Código de lenguaje ISO 639 de dos letras
CC (Optional) Two letter ISO 3166 Country Code
enc (Optional) Character Encoding Code Set
The locale command can be used to examine your current configuration (as can echo $LANG),
while locale -a will list all settings currently supported by your system. The extent of the support for
any given language will vary.
The following tables list some selected language codes, country codes, and code set specifications.
Código Lenguaje
de Alemán
el Griego
en Inglés
es Español
fr Francés
ja Japonés
zh Chino
Código País
CA Canadá
CN China
DE Alemania
ES España
FR Francia
GB Britain (UK)
GR Grecia
JP Japón
NG Nigeria
US Estados Unidos
Código País
utf8 UTF-8
iso88591 ISO 8859-1 (Latín 1)
iso885915 ISO 8859-15 (Latín 10)
iso88596 ISO 8859-6 (Árabe)
iso88592 ISO 8859-2 (Latín 2)
See the gettext info pages (info gettext, or pinfo gettext) for a complete listing.
230
¿Necesito saber todo esto?
We have tried to introduce the major concepts and components which affect how text is encoded
and stored within Linux. After reading about character sets and language codes, one might be led to
wonder, do I really need to know about all of this? If you are using simple text, restricted to the Latin
alphabet of 26 characters, the answer is no. If you are asking the question 10 years from now, the
answer will hopefully be no. If you do not fit into one of these two categories, however, you should
have at least an acquaintance with the concept of internationalization, character sets, and the role
of the LANG environment variable.
Hopefully, as the open source community converges on a single encoding technique (currently
UTF-8 seems the most likely), most of these issues will disappear. Until then, these are some key
points to remember.
If you are interested in more information, several man pages provide a more detailed introduction to
the concepts outlined above. Start with charsets(7), and then follow with ascii(7), iso_8859_1(7),
unicode(7) and utf-8(7). Additionally, the iconv command can be used to convert text files from
one form of encoding to another.
Retomando cat
Hemos estado utilizando el comando cat para simplemente mostrar el contenido de archivos. Por
lo general, el comando cat genera una copia fiel de su entrada, sin modificaciones o conversiones.
Sin embargo, cuando se llama el comando cat con una de las siguientes opciones indicará la
presencia de tabulaciones, avances de línea y otras secuencias de control por medio de las
siguientes convenciones.
Opción Efecto
-E muestra avances de línea (ASCII 10) como $
-T muestra tabulaciones (ASCII 9) como ^I
-v muestra espacio en blanco y caracteres de control como ^n, con n indicando la secuencia
para el caracter de no impresión CTRL.
-A Muestra "todo", lo mismo que -vET
-t Muestra "todo" excepto avances de línea, lo mismo que -vT
-e Muestra "todo" excepto tabulaciones, lo mismo que -vE
A manera de ejemplo, a continuación el comando cat se utiliza para visualizar el contenido del
archivo de configuración /etc/hosts.
231
[student@station student]$ cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost station.example.com
127.0.0.1 rha-server
192.168.0.1 station1 station1.example.com www1 www1.example.com
192.168.0.51 station51 station51.example.com
192.168.129.201 z
Al utilizar la opción -A, la estructura de espacio en blanco del archivo se hace evidente, al
remplazar las tabulaciones por ^I y los avances de línea son representados por$.
Los comandos head y tail se han utilizado para visualizar las primeras y úĺtimas líneas de un
archivo, respectivamente. Pero, ¿de qué consta una línea? Imagínese trabajando en una máquina
de escribir: ¡clic! ¡clac! ¡clic! ¡clac! ¡clac! ¡sssiin! En lugar del ¡sssiin! del carro de la máquina al final
de cada línea se selecciona el caracter de avance de línea (ASCII 10) para marcar el final de
líneas.
Hoy en día no se comparte entre todos los sistemas operativos dominantes en uso una sóla
convención para marcar el final de una línea. Linux (y Unix) utilizan el caracter de avance de línea
(ASCII 10, a menudo representado \n), mientras que los sistemas operativos de Macintosh utilizan
el caracter de retorno de carro (ASCII 13, a menudo representado \r o ^M) y los sistemas
operativos de Microsoft utilizan un par de retorno de carro/avance de línea (ASCII 13, ASCII 10).
Si este archivo fuese creado en un sistema operativo de Microsoft o Macintosh y copiado dentro de
Linux, los archivos se verían de la siguiente manera.
232
[student@station student]$ cat -A musicians.dos
elvis^M$
blondie^M$
prince^M$
madonna^M$
[student@station student]$ cat -A musicians.mac
elvis^Mblondie^Mprince^Mmadonna^M[student@station student]$
Los archivos de texto de Linux (y Unix) por lo general se adhieren a la convención de que el último
caracter del archivo debe ser un avance de línea para la última línea de texto. Siguiendo el cat del
archivo musicians.mac, que no contiene ninguno de los caracteres convencionales de avance de
línea de Linux, el intérprete de comandos bash no se visualiza en el sitio acostumbrado.
Opción Efecto
-N, -nN Muestra las primeras líneas N del archivo.
-cN Muestra los primeros N bytes del archivo.
Opción Efecto
-N, -nN Muestra las dos últimas líneas N del archivo. Si N se antepone a un + muestra el archivo
restante que comienza en la cuarta línea.
-cN Muestra los primeros N bytes del archivo.
¿Alguna vez ha tratado de contestar un test de “25 palabras o menos”? ¿Alguna vez ha tenido que
escribir un ensayo de 1.500 palabras?
Con wc puede verificar fácilmente que su aporte cumpla con los criterios.
Opción Resultados
-c Conteo de caracteres de cómputo.
-l Conteo de línea de cómputo.
-w Conteo de palabras de cómputo.
filename El nombredearchivo que se va a contar. Si no se especifica ningún nombredearchivo,
entonces el texto se leerá desde la entrada estándar. Para mayor claridad, el
nombredearchivo será escrito como la última línea de cada informe de conteo, incluso si
sólo se utiliza sólo un nombredearchivo.
233
Cuando se utiliza sin opciones, wc reportará el número de caracteres, líneas y palabras. Las
opciones pueden combinarse para retornar cualquier combinación de conteo de caracteres, de
líneas o de palabras.
Los archivos de texto están compuestos por un alfabeto de caracteres. Algunos caracteres son
visibles, tales como números y letras. Algunos caracteres se utilizan para distancia horizontal tales
como espacios y caracteres TAB. Algunos caracteres se utilizan para movimiento vertical tales
como retornos de carro y avances de línea.
Una línea en un archivo de texto es una serie de cualquier caracter diferente a un caracter
NEWLINE (avance de línea). Las líneas adicionales en el archivo siguen inmediatamente la
primera línea.
Aunque un computador representa caracteres como números, el valor exacto utilizado para cada
símbolo varía dependiendo del alfabeto que se escoja. El alfabeto más utilizado por los hablantes
de inglés es ASCII, también llamado “Latín-1”. Otras lenguas son representadas por reglas de
codificación diferentes, para que el valor numérico exacto para un determinado caracter dependa
del lenguaje humano que se está registrando.
Una palabra es un grupo de caracteres de impresión tales como letras y dígitos, rodeados por un
espacio en blanco, tales como caracteres de espacio o caracteres horizontales TAB.
Observe que la definición de una palabra no incluye ninguna noción de “significado”. Sólo la forma
de la palabra es importante, no su semántica. En lo que respecta a Linux, una línea tal como:
Ejemplos
Caracteres de conteo
Además de las cinco letras en la palabra, la línea también tiene un caracter NL al final.
Los caracteres que usted no puede ver también ocupan espacio en un archivo.
234
[student@station student]$ echo Hello, World! > greetings
[student@station student]$ wc -c greetings
14
Tenga en mente también que los espacios y TABs se cuentan como caracteres. ¿Recuerda la
analogía con la máquina de escribir? Tanto el espaciador como el TABULADOR se deben pulsar, a
cada caracter en un archivo de texto le corresponde el golpe de una tecla de una máquina de
escribir.
¿Cuál es mi línea?
¿Cómo manejaría el comando wc los tres archivos de los músicos mencionados anteriormente
(uno escrito en una máquina de Linux, uno en una máquina Microsoft y otro en una Macintosh)?
En la salida anterior, ¿por qué el archivo musicians.dos tiene 33 caracteres mientras que musicians
y musicians.mac tienen sólo 29?
Conteo de usuarios
235
El comando wc suele utilizarse para contar el número de cosas, no sólo líneas, palabras y
caracteres. Por ejemplo, el comando users genera una lista de usuarios que están actualmente en
la máquina. La siguiente línea crearía un alias denominado nusers, el cual reportaría el número de
usuarios actualmente en la máquina.
Procesos de conteo
Al examinar la salida de un comando tal como ps aux, el cual imprime en pantalla información
sobre un proceso por línea, el comando wc -l puede utilizarse para contar el número de procesos
ejecutándose en una máquina. Sin embargo, al examinar la salida de ps aux, la línea inicial que
contiene los títulos en columna debe suprimirse de la cuenta.
El comando tail, con su habilidad para imprimir el remanente de un archivo iniciando a partir de
una línea especificada, puede suprimirse de la línea de encabezado.
El siguiente script corto combina ps aux, tail +2 y wc para crear un nuevo comando llamado
nprocs. Cuando se hace ejecutable y se coloca en el directorio ~/bin (el cual es parte de una
búsqueda estándar ejecutable PATH), el script queda disponible desde la línea de comandos.
236
[student@station student]$ cat nprocs
#!/bin/bash
ps aux | tail +2 | wc -l
[student@station student]$ mkdir bin
[student@station student]$ mv nprocs bin
[student@station student]$ chmod a+x bin/nprocs
[student@station student]$ nprocs
86
Ejercicios en línea Lab Exercise Objetivo: Usar el comando wc como herramienta de conteo.
Estimated Time: 10 mins.
Especificaciones
1. Cree el archivo ~/gplwords.txt que contenga el número de palabras (como fue reportado
por el comando wc) en el archivo /usr/share/doc/redhat-release-4ES/GPL como su única
palabra.
2. Cree el archivo ~/localusers.txt, el cual contiene el número de usuarios localmente
definidos como su única palabra.
3. Las bibliotecas compiladas estáticamente de modo convencional se encuentran en el
directorio/usr/lib y tienen nombres que comienzan por lib y terminan en la extensión .a.
Cree el archivo ~/usrlibs.txt que contenga el número de los archivos cuyo nombre siga esta
convención en el directorio /usr/lib como su única palabra (no incluya subdirectorios).
4. Crear un script ejecutable llamado~/bin/nrecent. El script debería esperar un solo
argumento, el cual es un nombre de un directorio. Tras la ejecuación, el script debería
retornar un solo número, el cual es el número de archivos en el directorio modificados en
las últimas 24 horas. El script no debería generar mensajes de error de los directorios en el
flujo de error estándar.
Si usted ha implementado los ejercicios de modo correcto, debería poder reproducir una salida
semejante a la siguiente (no se preocupe si sus números reales difieren de los listados abajo).
237
3. Un archivo llamado ~/usrlibs.txt que contiene el número de archivos que comienzan por lib
y terminados en .a que se encuentran en el directorio /usr/lib.
4. Un script ejecutable llamado ~/bin/nrecent, que espera el nombre de un directorio como su
único argumento. Tras la ejecución, el script devolvería un solo número el cual es el
número de archivos bajo el directorio especificado modificados en las últimas 24 horas. El
script no debe retornar mensajes de error sobre directorios en el flujo de error estándar.
Ayudas
Para el archivo ~/localusers.txt recuerde que los usuario locales están definidos en el archivo
/etc/passwd, un usuario por línea.
Para el script ~/bin/nrecent recuerde que $1 desreferencia un argumento del script bash. Considere
el utilizar el comando find para generar una lista de archivos coincidentes con los criterios y luego
cuente el número de líneas (o palabras) en la salida. Usted podría desear utilizar los directorios /etc
o /var/log para probar su script.
238
Búsqueda de Texto: grep
Conceptos clave
• grep es un comando que imprime en pantalla líneas coincidentes con un patrón de una
cadena de texto especificado.
• grep suele utilizarse como filtro para reducir salida a sólo lo deseado.
• grep -r buscará de modo recursivo bajo un directorio determinado.
• grep -v imprime líneas NO coincidentes con una cadena o patrón de texto.
• Muchas de las opciones permiten a los usuarios especificar el formato de salida de grep.
Discussion
En una lección anterior, vimos cómo el programa wc puede utilizarse para contar los caracteres,
palabras y líneas en archivos de texto. En esta lección presentamos el programa grep, una
herrramienta útil para la búsqueda de palabras específicas o secuencias de caracteres en el
contenido de archivo de texto.
El nombre grep representa en inglés general regular expression parser. Usted puede preguntarse,
¿qué es una expresión regular y ¿por qué razones usted quisiera analizar una expresión regular
sintácticamente? Daremos una definición más formal de las expresiones regulares en una lección
posterior, pero por ahora es suficiente saber que una expresión regular es simplemente una forma
de describir un patrón o plantilla, para hacer coincidir con alguna secuencia de caracteres. Una
expresión regular sencilla sería “Hello”, la cual coincide exactamente con cinco caracteres: “H”, “e”,
dos caracteres consecutivos “l” y un caracter “o” final. Patrones de búsqueda de mayor alcance son
posibles y los examinaremos en la siguiente sección.
fgrep
Hace una búsqueda rápida de patrones simples. Utilice este comando para localizar
rápidamente patrones sin caracteres comodines, útil para buscar una palabra común.
grep
egrep
239
Búsqueda de patrones con expresiones regulares extendidas de gran alcance.
El argumento del patrón proporciona caracteres de plantillas que grep debe buscar. Se espera que
el patrón sea un solo argumento, por lo tanto si el patrón contiene espacios u otros caracteres
especiales de la shell, usted debe encerrar el patrón entre comillas para evitar que la shell lo
expanda o lo divida.
El cuadro a continuación resume algunas de las opciones más utilizadas de grep. Consulte la
página del manual grep(1) (o invoque grep --help) para mayor información.
Opción Efecto
-c Imprime un conteo de las líneas coincidentes únicamente.
-h Suprime prefijos de nombres de archivos.
-e Utiliza expresión como un patrón de búsqueda, (útil para especificar varios patrones
expresión alternos).
-i Ignora las mayúsculas o minúsculas al determinar coincidencias.
-l Imprime nombres de archivos que contienen solo un patron coincidente.
-n Incluye números de línea a lo largo de las líneas coincidentes.
-q "Quieto" No escriba nada a la salida estándar. En su lugar, salga con un estatus de
salida cero si encuentra algún archivo coincidente.
-r Busca todos los archivos de modo recursivo a través de directorios.
-w Sólo coincide con palabras completas.
-C Incluye dos líneas de contexto antes y después de la línea coincidente.
En Linux, hay varias formas de realizar la misma tarea. Por ejemplo, para ver si un archivo contiene
la palabra “even”, podría tan solo examinar visualmente el archivo:
Al leer el archivo, vemos que sí contiene las letras “even”. Al emplear este método en un archivo
grande se sufre porque podemos fácilmente perder una palabra en un archivo de varios miles o
incluso cientos de miles de palabras. Podemos utilizar la herramienta grep para que nos busque el
archivo de una forma automática:
Aquí buscamos una palabra con su deletreo exacto. En lugar de buscar una cadena de texto literal,
el argumento del patrón puede también ser una plantilla general para coincidir con secuencias de
caracteres más complicadas, eso lo veremos con detenimiento en una próxima lección.
240
Una forma fácil para buscar varios archivos es nombrarlos en la línea de comandos grep:
[student@station student]$ echo Every cat has one more tail than no cat.
> general
[student@station student]$ echo No cat has nine tails. > specific
[student@station student]$ echo Therefore, every cat has ten tails. >
fallacy
[student@station student]$ grep cat general specific fallacy
general:Every cat has one more tail than no cat.
specific:No cat has nine tails.
fallacy:Therefore, every cat has ten tails.
Quizás estemos más interesados en descubrir el archivo que menciona la palabra “nine” que en ver
la línea misma. Al añadir la opción -l a la línea grep hace justo eso:
Grep también puede buscar con un solo comando todos los archivos en un árbol de directorio
completo. Esto puede ser útil si trabajamos con un gran número de archivos.
La forma más fácil de entender esto es verlo en acción. En el directorio /etc/sysconfig hay tres
archivos de texto que contienen mucha de la información de configuración del sistema de Linux. El
nombre Linux para el primer dispositivo de red de Ethernet en un sistema es “eth0”, usted puede
buscar qué archivo contiene la configuración para eth0 al permitirle al comando grep -r hacer la
búsqueda por usted[1]:
Podemos más adelante limitar los archivos listados a sólo aquellos que se refieran al dispositivo
real, filtrando la salida de grep -r a través de un grep DEVICE:
241
[student@station student]$ grep -r eth0 /etc/sysconfig 2>/dev/null |
grep DEVICE
/etc/sysconfig/network-scripts/ifcfg-eth0:DEVICE='eth0'
/etc/sysconfig/networking/devices/ifcfg-eth0:DEVICE='eth0'
/etc/sysconfig/networking/profiles/default/ifcfg-eth0:DEVICE='eth0'
Esto muestra un uso común de grep como filtro para simpl¡ficar las salidas de otros comandos.
Si solamente los nombres fueran de interés, la salida podría simplificarse con la opción -l.
Inversión de grep
La herramienta grep muestra por defecto sólo las líneas coincidentes con el patrón de búsqueda.
Esto suele ser lo deseado, pero algunas veces se puede tener interés en las líneas no coincidentes
con el patrón. En estas instancias, la opción -v invierte el funcionamiento de grep.
Usted puede estar buscando con frecuencia un archivo grande que tiene varias ocurrencias del
patrón. Grep listará cada línea que contiene una o más coincidencias, ¿pero cómo se hace para
localizar aquellas líneas en el archivo original? Utilizando el comando grep -n también listará el
número de cada línea coincidente.
242
También podría querer combinar la opción -n con la opción-r al buscar en los siguientes archivos
de directorio:
Suponga que queremos recuperar todas las líneas que contienen la palabra “at”. Si ensayamos el
comando:
¿Ve lo que sucedió? Hicimos coincidir con la cadena de texto“at” ya sea que fuera una palabra
aislada o parte de una palabra más grande. El comando grep proporciona la opción -w para
implicar que el patrón especificado sólo debería coincidir con palabras enteras.
La opción -w considera como una palabra a una secuencia de letras, números y caracteres de
subrayado, rodeados por cualquier otra cosa.
La cadena “Bob” tiene un significado bastante diferente a la cadena “bob”. Sin embargo, algunas
veces queremos encontrar cualquiera sin importarnos si la palabra está en mayúsculas o no. El
comando grep -i resuelve justo este problema.
243
[student@station student]$ cat rhyme
The cat
sat on
the mat
at home.
Ahora observe qué líneas contienen las letras “t”, “h” y “e” en cualquier combinación de letras
mayúsculas y minúsculas:
Observe que también utilizamos la opción -n para agregar los números de línea a la salida.
Ejemplos
Verifique que su computador tenga la cuenta del sistema “lp”, utilizada por la línea de herramientas
de impresión. Ayuda: el archivo /etc/passwd contiene una línea por cada cuenta de usuario en el
sistema.
Nada coincidió debido a que el patrón no coincidió con el tipo de letra para el nombre de cuenta.
Busque de nuevo ignorando las mayúsculas y minúsculas:
244
Palabras completas coincidentes
Hemos visto que grep coincidirá con el patrón siempre que el patrón esté situado, incluso en medio
de palabras. Busque el patrón“honey” en el diccionario de palabras del sistema
/usr/share/dict/words:
Es evidente que el diccionario contiene varias palabras con la cadena “honey” como una palabra
root. Podemos limitarnos a hacer coincidir un montón de palabras utilizando el comando grep -w.
El comando grep considera que una palabra es un grupo de letras, dígitos o caracteres de
subrayado rodeados por cualquier otra cosa. El comienzo y fin de una línea también clasifica como
“cualquier otra cosa”, por lo tanto la primera y última palabra en una línea se reconoce
correctamente. De nuevo, trate de buscar“honey” en el diccionario:
Usted desearía ahora buscar cada ocurrencia del textocommandline y cambiarla por command line.
Comienza por identificar los archivos que contienen el texto commandline.
245
[student@station student]$ grep -ril commandline /usr/share/doc/vim*
/usr/share/doc/vim-common-6.1/docs/message.txt
/usr/share/doc/vim-common-6.1/docs/options.txt
/usr/share/doc/vim-common-6.1/docs/os_risc.txt
/usr/share/doc/vim-common-6.1/docs/tags
/usr/share/doc/vim-common-6.1/docs/todo.txt
/usr/share/doc/vim-common-6.1/docs/various.txt
/usr/share/doc/vim-common-6.1/docs/version5.txt
Usted desearía abrir cada uno de estos archivos en el editor de texto gedit para hacer sus
modificaciones. Entuba los resultados de su búsqueda en el comando gedit.
El editor gedit se abre, pero con un buffer vacío llamado"sin título". ¡Esto no es lo que quería!
Usted quería que gedit abriera los nombres de archivo provistos por el comando grep en la
entrada estándar, no la entrada estándar misma. Sin embargo, así funciona gedit. gedit (al igual
que la mayoría de los editores de texto) espera que los nombres de archivo estén provistos de
argumentos en la línea de comandos, no mediante la entrada estándar.
Afortunadamente, existe la utilidad estándar de Linux (y Unix): xargs, la cual ayuda justo en
situaciones como éstas. El comando xargs leerá la entrada estándar y añadirá las palabras
encontradas en la línea de comandos provista, a manera de argumentos adicionales. Esperemos
que el siguiente ejemplo lo aclare. Con su conocimiento acerca del comando xargs modifique su
método anterior.
Ahora, el editor gedit se abre con múltiples memorias inmediatas, una para cada salida de archivo
con el comando grep.
Figure 1. Uso de xargs para convertir la entrada estándar en argumentos para gedit
Observe que nunca ha tenido que teclear nombres de archivos individuales. Las palabras provistas
en la entrada estándar fueron intercambiadas por argumentos en la línea de comandos, para esto
sirve el nombre xargs. ¡Muy útil!
Ejercicios en línea Lab Exercise Objetivo: Usar el comando grep para buscar ocurrencias de
texto específico. Estimated Time: 10 mins.
Especificaciones
1. Crear el archivo ~/bashusers.txt que contenga las líneas del archivo /etc/passwd que
contengan el texto /bin/bash.
2. Crear el archivo~/nostdhome.txt que contenga sólo líneas desde el archivo /etc/passwd
que no contengan el texto home (implicando que el usuario asociado tiene un directorio de
inicio no estándar).
246
3. Crear el archivo ~/ansiterms.txt que contenga cada línea del archivo /etc/termcap que
contenga el texto ansi, utilizando una búsqueda insensible a las mayúsculas y minúsculas,
(en otras palabras, ansi, ANSI, Ansi y AnSi todas coincidirían).
4. Crear el archivo ~/mayhemnum.txt que contenga el número de la línea de la palabra
mayhem del archivo /usr/share/dict/words como su única palabra.
5. Crear el archivo ~/firstredhat.txt que contenga un listado clasificado en orden alfabético de
todos los archivos bajo el directorio /usr/share/firstboot (y sus subdirectorios) que
contengan el texto redhat, utilizando una búsqueda que no tenga en cuenta las mayúsculas
y minúsculas. Los archivos deben listarse uno por línea mediante referencias absolutas.
1. El archivo ~/bashusers.txt que contenga líneas del archivo /etc/passwd que contengan el
texto /bin/bash.
2. El archivo ~/nostdhome.txt que contenga líneas del archivo /etc/passwd que no contengan
el textohome.
3. El archivo ~/ansiterms.txt que contenga cada línea del archivo /etc/termcap que contenga
el texto ansi, mediante una búsqueda sin tener en cuenta las mayúsculas y minúsculas.
4. El archivo ~/mayhemnum.txt que contenga el número de línea de la palabra mayhem del
archivo /usr/share/dict/words como su única palabra.
247
Introducción a las expresiones regulares
Conceptos clave
• Las expresiones regulares son una sintaxis estándar de Unix para especificar los patrones
de texto.
• Las expresiones regulares son entendidas por muchos comandos incluyendo grep, sed, vi
y varios lenguajes de escritura.
• Dentro de las expresiones regulares, . y [] se utilizan para coincidir caracteres.
• Dentro de las expresiones regulares, +, * y? especifican un número de ocurrencias
consecutivas.
• Dentro de las expresiones regulares ^ y $ especifican el comienzo y el final de una línea.
• Dentro de las expresiones regulares, (, ) y| especifican grupos alternativos.
• La página del manual regex (7) proporciona detalles completos.
Discussion
En el capítulo anterior se describió grep para coincidir una parte o toda una palabra. Esto de por sí
es poderoso especialmente junto con otros argumentos como -i y -v, pero no es apropiado para
todos los escenarios de búsqueda. A continuación se presentan algunos ejemplos de búsquedas
que la herramienta grep que hemos estudiado hasta el momento no puede realizar:
==========================
Name: Sarah Jane
Age: 29
Pets:
Name: Orfeus
Age: 7
Species: Dog
-------------
Name: Euridice
Age: 8
Species: Dog
248
¿Qué sucedería si quisiera sacar únicamente los nombres de las personas en
people_and_pets.txt? Un comando como grep -w Name: coincidiría con el 'Name:' línea para cada
persona, pero también el 'Name:' línea para cada mascota de las personas. ¿Cómo podríamos
hacer coincidir sólo el 'Name:' líneas para las personas? Observe que las líneas para nombres de
mascotas tienen todas sangría, lo que significa que esas líneas comienzan por caracteres de
espacio en blanco en lugar de texto. Entonces, podríamos realizar una meta si tuviéramos una
forma de decir "Muéstreme todas las líneas comenzadas por 'Name:'".
Otro ejemplo: suponga que usted y un amigo suyo vieron un accidente de auto. Ambos vieron el
número de la placa del auto que se escapó, sin embargo, cada uno recuerda el número con
algunas diferencias. Usted leyó el número de la placa como "4I35VBB", pero su amigo leyó
"413SV88". Parece que usted leyó como una 'I' el segundo caracter y su amigo lo leyó como un '1'.
Diferencias similares aparecen en sus interpretaciones de otras partes de la placa como '5' en lugar
de 'S' y 'BB' en lugar de '88'. Habiendo tomado ambas declaraciones, la policía necesita ahora
acortar la lista de los sospechosos consultando su base de datos con las placas que puedan
coincidir con las que ustedes vieron.
Una solución podría ser realizar peticiones por separado para "4I35VBB" y "413SV88", pero al
hacer esto se asume que uno de ustedes estaba en lo cierto. ¿Qué sucedería si el número de la
placa del causante del accidente fuera realmente "4135VB8"? En otras palabras, qué sucedería si
usted tuviera algunos caracteres correctos, pero su amigo tuviera otros correctos? Sería más
efectivo si la policía pudiera preguntar por un patrón que efectivamente dijera: "Muéstreme todos
los números comenzados por un '4', seguidos por una 'I' o por un '1', seguido por un '3', seguido
por un '5' o una 'S', seguido por una 'V', seguido por dos caracteres que sean una 'B' o un '8'".
Escenarios como estos se pueden resolver utilizando expresiones regulares. Aunque los científicos
informáticos algunas veces utilizan el término "expresión regular " (o "regex" para acortar) para
describir cualquier método de descripción de patrones complejos, en Linux y muchos lenguajes de
programación, el término se refiere a un conjunto de caracteres muy específico utilizado para
resolver problemas como el anterior. Las expresiones regulares son compatibles con un gran
número de herramientas incluyendo grep, vi, find y sed.
Para introducir el uso de expresiones regulares, veamos algunas soluciones a dos problemas
descritos anteriormente. No se preocupe si estos parecen un poco complicados, el resto de la
unidad comenzará desde el principio y cubrirá expresiones regulares detalladamente.
Una regex que pueda resolver el primer problema, donde queríamos decir "Muéstreme todas las
líneas que comienzan por 'Name:'" podría verse así:
...eso es! Las expresiones regulares tienen que ver con el uso de caracteres especiales llamados
metacaracteres para representar parámetros de búsqueda avanzada. El acento circunflejo ("^"),
como se muestra aquí significa "Líneas que comienzan por...". A propósito, observe que la
expresión regular está en comillas sencillas. Es un buen hábito entrar pronto porque así se evita
que bash interprete caracteres especiales destinados para grep.
Está bien, ¿entonces qué pasa con el segundo problema? Este último involucra una pregunta un
poco más compleja: "Muéstreme todos los números de placas que comienzan por '4', seguido por
una 'I' o un '1', seguido por un '3', seguido por un '5' o una 'S', seguida por una 'V', seguido por dos
caracteres que sean una 'B' o un '8'". Esto podría representarse con una expresión regular así:
249
4[I1]3[5S]V[B8]{2}
¡Oh! es bastante corta si consideramos el tiempo que nos tomó escribir lo que estamos buscando!
Hay sólo dos tipos de metacaracteres regex utilizados aquí: los paréntesis cuadrados ('[]') y los
paréntesis curvos ('{}'). Cuando dos o más caracteres se muestran dentro de paréntesis significa
"cualquiera de estos". Entonces '[B8]' cerca del final de la expresión significa "'B' u '8'". Cuando un
número se muestra sin ningún paréntesis curvo significa "estos cuantos del caracter anterior". Por
lo tanto, '[B8]{2}' significa "dos caracteres que sean una 'B' o un '8'". ¡Un argumento bastante
convincente!
Ahora que sabe el significado y la utilidad de las expresiones regulares, comencemos desde el
principio y cubrámoslas a fondo.
Uno de los usos más comunes para expresiones regulares es especificar patrones de búsqueda
para el comando grep. Como lo mencionamos en una lección anterior, hay tres versiones del
comandogrep. Reiterando, los tres difieren en la manera de interpretar expresiones regulares.
fgrep
El comando fgrep está diseñado para ser un grep "rápido". El comando fgrep no soporta
expresiones regulares, pero en su lugar interpreta cada caracter en un patrón de búsqueda
especificado literalmente.
grep
El comando grep interpreta cada patrón mediante la sintaxis básica original de expresión
regular.
egrep
El comando egrep interpreta cada patrón mediante la sintaxis expresión regular extendida.
Dado que no estamos distinguiendo entre una sintaxis de expresión regular básica y una
extendida, el comando egrep debería utilizarse cada vez que el patrón de búsqueda contenga
expresiones regulares.
250
una expresión regular, estábamos utilizando una expresión regular de cinco caracteres. Aunque
esto nos permitió concentrarnos en cómo operar el programa grep, no nos permitió obtener una
apreciación completa del poder de las expresiones regulares. Antes de ver las expresiones
regulares, primero deberíamos ver cómo están construídas.
Caracteres literales
Los caracteres literales coinciden únicamente con ellos mismos. Las letras, dígitos y la
mayoría de los caracteres son ejemplos de caracteres literales (vea a continuación las
excepciones).
Comodines
Los caracteres comodines coinciden con cualquier caracter. Dentro de una expresión, un
punto (“.”) coincide con cualquier caracter, ya sea un espacio, una letra, un dígito,
puntuación, cualquier cosa.
Modificadores
Un modificador altera el significado del caracter patrón precedente inmediato. Por ejemplo,
la expresión “ab*c” coincide con cadenas de texto “ac”, “abc”, “abbc”, “abbbc” y así
sucesivamente porque el asterisco (“*”) es un modificador que significa “cualquier número
de (incluyendo cero)”. De esta manera, nuestro patrón significa coincidir con cualquier
secuencia de caracteres que conste de una “a”, (posiblemente vacía) un conjunto de
caracteres “b” y un caracter final “c”.
Anclas
Las anclas establecen el contexto para el patrón tal como "el comienzo de una línea" o "el
final de una palabra". Por ejemplo, la expresión “cat” coincidiría con cualquier ocurrencia
de las tres letras mientras que “^cat” sólo coincidirían con las líneas que comienzan por
“cat”.
Los literales son directos porque cada caracter literal en una expresión regular coincide con una y
sólo con una copia de sí mismo en el texto examinado. Los caracteres en mayúsculas se
distinguen de los caracteres en minúsculas para que “A” no coincida con “a”.
Comodines
El comodín "punto"
El caracter “.” se utiliza como un marcador para coincidir con algún caracter. En el siguiente
ejemplo, el patrón coincide con cualquier ocurrencia de los caracteres literales “x” y “s” separados
exactamente por dos caracteres.
251
[student@station student]$ grep "x..s" /usr/share/dict/words | head -5
antitoxins
axers
axles
axons
boxers
Normalmente un caracter literal en un patrón regex coincide exactamente con una ocurrencia de sí
mismo en el texto examinado. Suponga que queremos buscar una cadena de texto “hello” sin
importar las mayúsculas: queremos hacer coincidir “Hello” y “HeLLo” también. ¿Cómo podríamos
hacer esto?
Una característica de regex llamada una expresión entre paréntesis resuelve el problema
claramente. Una expresión de paréntesis es un intervalo de literales encerrados entre paréntesis
cuadrados (“[” y “]”). Por ejemplo, el patrón regex “[Hh]” es una variedad de caracteres que
coinciden exactamente con uno: ya sea en “H” mayúscula o o en “h” minúscula. Observe que no
importa qué tan grande es el conjunto de caracteres dentro de un intervalo, el conjunto coincide
exactamente con un caracter, si éste coincide con alguno. Una expresión entre paréntesis
coincidente con el conjunto de vocales en minúsculas podría escribirse “[aeiou]” y coincidiría
exactamente con una vocal.
En el siguiente ejemplo, las expresiones entre paréntesis se utilizan para buscar palabras desde el
archivo /usr/share/dict/words. En el primer caso, las primeras cinco palabras que contienen tres
vocales consecutivas (en minúsculas) son impresas en pantalla. En el segundo caso, se imprimen
las primeras 5 palabras que contengan minúsculas en el patrón de vocal-consonante-vocal-
consonante-vocal-consonante.
252
Intervalo de expresiones versus clases de caracteres: vieja y nueva escuela
Otra forma de expresar un intervalo de caracteres es dar letras de arranque y final de la secuencia
de esta forma: “[a-d]” coincidiría con cualquier caracter del conjunto a, b, c o d. Un uso típico de
esta forma sería “[0-9]” para representar cualquier dígito sencillo o “[A-Z]” para representar todas
las letras mayúsculas.
¿Cómo se ordenan los caracteres? Por ejemplo, ¿la“C” mayúscula, va antes o después de “b”
minúscula? Recuerde la discusión acerca del caracter de codificación en la primera lección. El
valor codificado de la letra se utiliza para determinar si un caracter es "menor" o "mayor" que otro.
Mientras el conjunto de caracteres que define la codificación sea ordenado correctamente, como
en el caso de ASCII, todo está bien. Pero, ¿qué pasa con el conjunto de caracteres latino -1
(ISO-8859-1) ? ¿Es verdad que “” va después de “z”?
Como una alternativa a estos dilemas, la expresión regular moderna hace uso de las clases de
caracter. Las clases de caracter coinciden con cualquier caracter sencillo, utilizando convenciones
específicadas de lenguaje para decidir si determinado caracter es letra mayúscula o minúscula o si
debería considerarse como parte del alfabeto o como puntuación. El siguiente cuadro lista algunas
de las clases de caracteres y la expresión equivalente en el intervalo ASCII donde es apropiado.
Las clases de caracteres evitan problemas que se encuentran al usar expresiones regulares en
sistemas que utilizan diferentes esquemas de codificación de caracteres en donde las letras son
ordenadas de modo diferente. Por ejemplo, suponga que usted fuera a ejecutar el comando:
En un sistema de Red Hat Enterprise Linux, cada palabra coincidiría en el archivo, pero no sólo
aquellas que contengan mayúsculas como puede asumirse. Esto se debe a que en unicode (utf-8),
el esquema de codificación de caracteres que RHEL utiliza, están ordenados alfabéticamente sin
importar las mayúsculas o minúsculas para que [A-Z] sea equivalente a [AaBbCc...etc]. Sin
embargo, en sistemas menos recientes se utiliza un sistema de esquema de codificación de
caracteres diferente en donde el orden alfabético dado es sensible a las mayúsculas y minúsculas.
En dichos sistemas [A-Z] sería equivalente a [ABC...etc]. Las clases de caracteres evitan este
error. Usted puede ejecutar:
253
en cualquier sistema sin importar el esquema de codificación que se esté utilizando y sólo
coincidiría con las líneas que contengan mayúsculas.
Para mayor información acerca de los intervalos de expresiones predefinidas consulte la página
grep del manual. Para mayor información en esquemas de codificación de caracteres bajo Linux,
refiérase al capítulo 8.3. Si quiere aprender acerca de cómo se utilizan los esquemas de
codificación de caracteres para soportar otros idiomas en Red Hat Enterprise Linux, comience por
la página del manual locale.
Vimos un uso común del modificador regex en nuestro ejemplo reciente “ab*c” para coincidir con
un caractera y c con algún número de letras b intermedias. El caracter “*” cambió la interpretación
del caracter literal b de coincidir exactamente con una letra a coincidir con cualquier número de b.
b?
El signo de interrogación final (“?”) significa “uno o ninguno”: el caracter literal se considera
como opcional en el texto examinado. Por ejemplo, el patrón regex “ab?c” coincide con las
cadenas de texto “ac” y “abc”, pero no con “abbc”.
b*
El modificador asterisco (“*”) significa “cualquier número (incluyendo cero)” del caracter
literal precedente. El patrón regex “ab*c” coincide con las cadenas de texto “ac”, “abc”,
“abbc” y así sucesivamente.
b+
El modificador más (“+”) significa “uno o más”, por lo tanto el patrón regex “b+” coincide
con una secuencia de no-espacio vacío de b. El patrón regex “ab+c” coincide con las
cadenas de texto “abc” y “abbc” pero no coincide con “ac”.
b{m,n}
b{n}
En el siguiente ejemplo, egrep imprime líneas desde /usr/share/dict/words que contienen patrones
que comienzan con una (letra mayúscula o minúscula) “a”, luego podría o no tener una
“b”(minúscula), pero luego sin duda, seguida por una “a” (minúscula).
254
[student@station student]$ egrep '[Aa]b?a' /usr/share/dict/words | head
-5
Aarhus
Aaron
Ababa
aback
abaft
El siguiente ejemplo imprime líneas que contienen patrones que comienzan por“al”, luego usan el
comodín “.” para especificar 0 o más ocurrencias de cualquier caracter, seguidas por el patrón
“bra”.
Observe que hallamos variaciones en las palabras algebra y calibrate. Para la anterior, la expresión
.* coincidió con “ge” mientras que la última coincidió con la letra “i”.
La expresión “.*”, la cual se interpreta como "0 o más de cualquier caracter", aparece a menudo en
patrones regex, actuando como la "goma elástica " dentro de dos patrones importantes.
Notemos que los caracteres modificadores son ambiciosos: siempre quieren coincidir con la
cadena de texto más larga posible. Por ejemplo, dado el patrón regex:
t.*e
y el flujo de salida:
ahora es el momento
el tiempo
En lugar de sólo “the”. Cuando se utiliza para búsquedas tales como grep, la diferencia suele ser
insignificante. Sin embargo, cuando las expresiones regulares se utilizan para buscar y remplazar
operaciones, como se hace con muchos editores, la diferencia se vuelve importante.
255
Búsquedas de anclaje
^foo
Un acento circunflejo (“^”) coincide con el comienzo de una línea. Nuestro ejemplo, “^foo”
coincide con la cadena de texto“foo” sólo cuando está al comienzo de la línea.
foo$
Un signo de dólar (“$”) coincide con el final de una línea. Nuestro ejemplo “foo$” coincide
con la cadena de texto “foo” sólo al final de la línea inmediatamente antes del caracter
newline.
\<foo\>
Solos, los signos menor que (“<”) y mayor que (“>”) son literales. Al usar el caracter de
barra invertida para escaparlos significan “primero de una palabra ”y “fin de una palabra”,
respectivamente. De esta manera el patrón “\>cat\<” coincide con la palabra “cat”, pero no
con la palabra “catalog”.
Usted verá con frecuencia tanto^ como$ utilizados juntos. El patrón regex “^foo$” coincide con una
línea entera que contiene sólo “foo” y no coincidiría con la línea si ésta contuviera espacios.
En el siguiente ejemplo, la primera búsqueda lista todas las líneas que contienen las letras “ion” en
cualquier parte de la línea. La segunda, lista sólo líneas que terminen en “ion”.
De la misma manera que usted utiliza los paréntesis para agrupar términos dentro de una
expresión matemática, también utiliza paréntesis para recopilar especificadores de patrones de
expresiones regulares dentro de grupos. Esto le permite a los caracteres modificadores “?”, “*” y “+”
256
aplicarse a los grupos de especificadores de regex en lugar de sólo inmediatamente al
especificador anterior.
Suponga que necesitamos una expresión regular para coincidir ya sea con “foo” o “foobar”.
Podríamos escribir la regex como “foo(bar)?” y obtener los resultados esperados. Esto le permite al
modificador “?” aplicar toda la cadena de texto “bar” en lugar de únicamente al caracter precedente
“r”.
La agrupación de especificadores regex mediante paréntesis se hace aún más flexible cuando se
utiliza el símbolo de tubería (“|”) para separar patrones alternativos. Al utilizar alternativas,
podemos volver a escribir nuestro ejemplo anterior como “(foo|foobar)”. Escribir esto como “foo|
foobar” es más sencillo y funciona de la misma manera, porque al igual que en matemáticas, los
especificadores regex tienen prioridad. Mientras usted esté aprendiendo, siempre encierre los
grupos entre paréntesis.
Escape de Metacaracteres
Algunas veces usted necesita coincidir un caracter que comúnmente sería interpretado como un
comodín para una expresión regular o un caracter modificador. Para inhabilitar temporalmente el
significado especial de estos caracteres, simplemente escápelos mediante el caracter de barra
inversa (“\”). Por ejemplo, el patrón regex “cat.” coincidiría con las letras “cat” seguidas por
cualquier caracter: “cats” o “catchup”. Para coincidir sólo con las letras “cat.” al final de una oración,
utilice el patrón regex “cat\.” para inhabilitar el periodo de interpretación como un caracter comodín.
Observe una molesta excepción a esta regla. Cuando el caracter de barra inversa precede a “<” o
al caracter “>”, éste habilita la interpretación especial (fijando el comienzo o el final de una palabra)
en lugar de inhabilitar la interpretación especial. ¡Ni pensar en lo que pasará! Pero puede ser peor-
vea la nota de pie de página en la parte inferior del siguiente cuadro.
257
El cuadro siguiente resume la sintaxis de expresiones regulares e identifica los componentes
hallados en la sintaxis de expresión regular básica y en la sintaxis de expresiones regulares
extendidas.
Al encontrar expresiones regulares por primera vez se entiende que los estudiantes confundan las
expresiones regulares con la expansión del nombre de ruta (comodín de archivos). Ambos se
utilizan para hacer coincidir patrones en texto. Ambas comparten metacaracteres similares (“*”, “?”,
“[...])”, etc.). Sin embargo, son bien diferentes. El siguiente cuadro compara y contrasta expresiones
regulares y comodines de archivos.
258
Utiliza la expresión “.” para coincidir Utiliza la expresión “?” para coincidir
exactamente con cualquier caracter. exactamente con cualquier caracter.
En el siguiente ejemplo, el primer argumento es una expresión regular especificando texto que
comienza por “l” y terminando en “.conf”, mientras que el segundo argumento es un comodín de
archivo que especifica todos los archivos en el directorio /etc cuyo nombre de archivo comienza por
“l” y termina en “.conf”.
Observe de cerca la segunda línea de salida. ¿Por qué fue emparejada por la expresión regular
especificada?
Apenas hemos tocado el tema de la utilidad de las expresiones regulares. La explicación provista
será adecuada a sus necesidades diarias, pero aún así, las expresiones regulares ofrecen mucho
más poder, al facilitar búsquedas de texto aún mas complicadas.
Ejemplos
Búsquedas literales
Ahora que entendemos las expresiones regulares en mayor detalle volvamos a ver algunos
ejemplos anteriores con una nueva perspectiva.
259
• el at en “cat” y
• el at en “mat” y
• el at en “at”.
Intervalo de expresiones
El intervalo de expresión “[cf]ar” coincide con una c o con una f seguida por “ar”.
Modificadores REGEX
Los modificadores controlan cuántas ocurrencias del especificador anterior regex coinciden:
El signo de interrogación (?) coincide exactamente con una ocurrencia del especificador
precedente, si éste existe.
El signo más (+) coincide con uno o más de los especificadores precedentes:
El asterisco (*) coincide con cualquier número, incluyendo cero, de ocurrencias del especificador
precedente:
260
[student@station student]$ egrep 'ab*c' file
ac
abc
abbc
abbbc
Búsquedas de anclaje
Las búsquedas de anclaje se utilizan para hallar coincidencias entre el comienzo y el final de la
línea de entrada.
Donde ^ y $ se fijan a las líneas, las anclas \< y \> coinciden con el comienzo y el final de las
palabras:
Utilice paréntesis para agrupar varios especificadores regex dentro de una sóla unidad. Utilice el
símbolo de tubería (“|”) para indicar alternativas.
Suponga que estamos escribiendo una carta en inglés. Podríamos escribir una expresión regular
para coincidir con la línea de saludo como esta:
^Dear (Dr|Mr|Ms)\.
261
Esto coincidiría con las líneas:
Quizás el saludo no coincidió porque olvidamos agregar el punto después de la abreviatura. Este
patrón regex coincidiría de la siguiente manera:
^Dear (Dr|Mr|Ms)\.?
La usuaria blondie quisiera crear un guión que revise si alguien está definido como un usuario local
en un sistema Linux. El guión toma un argumento, el cual se espera sea un nombre de usuario.
Ella podría utilizar el comando id para confirmar si existe un usuario llamado username, pero el
comando id incuiría usuarios que podrían definirse por un servidor NIS o algún otro tipo de base de
datos de acceso a la red, en lugar de la máquina local. Ella en su lugar, decide examinar
directamente la base de datos local del usuario (el archivo/etc/passwd).
if [ ! $# == '1' ]; then
echo "usage: inhouse USERNAME"
exit 1
fi
262
Al grabar el archivo y hacerlo ejecutable, blondie ensaya el guión en el usuario elvis (existente) y
en el usuario barney (no existente).
Comienza por observar el hecho que los número de los Estados Unidos tienen al menos 7 dígitos,
por convención escritos con los primeros tres dígitos separados de los últimos cuatro ya sea con un
“-” o con un espacio, tal como 555-1212 o 555 1212. Comienza por buscar dicho patrón de modo
recursivo a través de todos los archivos en el directorio /usr/share/doc.
Después de observar las primeras pocas líneas, elvis nota que su patrón regex es demasiado
general. Está buscando todos los códigos postales como también los números telefonónicos.
Refina su patrón de búsqueda especificando que cualquier caracter precedente o de rastro no debe
ser un número.
263
Esta vez, la búsqueda de elvis precede mucho mejor, hasta que él toque el archivo esound.ps.
Este archivo contiene PostScript, el cual por rutina utiliza números escritos en texto ASCII para
especificar coordenadas. Al saber que no estaba examinando un archivo PostScript, elvis diseña
una forma de excluir todos los archivos terminados en la extensión .ps desde su búsqueda.
Primero utiliza el comando find para listar cada archivo en el directorio. Luego la salida de grep a
todos los archivos no terminados en .ps. Entonces utiliza el comando xargs para alimentar estos
nombres de archivos dentro de su comando original grep como argumentos. Puesto que sus
archivos están siendo especificados de modo individual la línea de comandos ya no necesita
utilizar grep de modo recursivo.
Ahora que la búsqueda parece ir bien, elvis revisa la salida formateando y pidiéndole a grep no
mostrar los nombres de archivos y dar 2 líneas de contexto alrededor de cada número telefónico.
264
[elvis@station doc]$ find . | egrep -v '\.(ps|pdf|fig)$' |
xargs egrep -h -C2 '[^[:digit:]][[:digit:]]{3}(-| )[[:digit:]]{4}[^[:digit:]]'
it's much cheaper and includes a great deal of useful explanatory material.)
In the USA, copies of the standard may be ordered from ANSI Sales at (212)
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
doesn't take credit card orders, but Global does.) It's not cheap: as of
1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
--
1778 McCarthy Blvd.
Milpitas, CA 95035
phone (408) 944-6300, fax (408) 944-6314
A PostScript version of this document is available by FTP at
ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text
--
The Free Software Foundation sells tapes and CD-ROMs
containing Bash; send electronic mail to
\f([email protected]\fP or call \f(CR+1-617-876-3296\fP
for more information.
.PP
--
# --
# Aharon (Arnold) Jones [email protected] [ <<=== NOTE: NEW
ADDRESS!! ]
# P.O. Box 354 Home Phone: +972 8 989-0381 Fax: +1 603 761-6761
# Nof Ayalon Cell Phone: +972 51 227-545 (See www.efax.com)
# D.N. Shimshon 97784 Laundry increases exponentially in the
--
The Ohio State University http://www.math.ohio-state.edu/~nevai/
231 West Eighteenth Avenue http://www.math.ohio-state.edu/~jat/
Columbus, Ohio 43210-1174 1-614-292-5310 (Office/Answering Device)
The United States of America 1-614-292-1479 (Math Dept Fax)
--
,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,
Joe Farwell | phone 610-843-6020 | Platinum technology
Systems Administrator | vmail 800-123-9096 x7512 | 620 W. Germantown Pike
[email protected] | fax 610-872-6021 | Plymouth Meeting,Pa,19462
'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'
delay needs to be calibrated using outside sources.
...
Observe que los nombres y números han sido alterados en esta salida.
Elvis termina con 289 " coincidencias " las cuales puede revisar en un tiempo razonable.
Ejercicios en línea Lab Exercise Objetivo: Usar expresiones regulares para buscar patrones de
texto.Tiempo estimado: 45 minutos.
Especificaciones
265
script debería imprimir en pantalla el número 1. De lo contrario, el script debería imprimir en
la pantalla el número 0.
2. Usted está buscando archivos en el directorio /etc (pero no en subdirectorios) que
contengan un número estándar de larga distancia en los Estados Unidos, escrito mediante
el patrón 1-###-###-####, donde cada # es remplazado por un dígito numérico. Recopile
los nombres de archivos de cada archivo en el directorio /etc que contenga dicho patrón de
números y colóquelos en el archivo ~/etcphone.txt, un archivo por línea, clasificado en
orden alfabético, usando referencias absolutas.
3. El archivo /usr/share/doc/bash-*/NEWS contiene muchas listas detalladas, con los
elementos de la lista marcados por líneas cuyos caracteres sean una serie de una o más
letras, seguidas por un punto y un espacio como a continuación:
y. New prompting expansions: \a, \e, \H, \T, \@, \v, \V.
Crear los siguientes archivos, cada uno conteniendo el número que contesta la pregunta
especificada como su palabra única.
filename pregunta
newsitems.txt ¿Cuántas líneas comienzan por una serie de una o máś letras seguidas por un
punto?
newsitems23.txt ¿Cuántas líneas comienzan por una serie de dos o tres letras seguidas por un
punto?
newsitems2.txt ¿Cuántas líneas comienzan por una serie exacta de dos letras seguidas por un
punto?
newsitems3.txt ¿Cuántas líneas comienzan por una serie exacta de tres letras, seguidas por un
punto?
Al utilizar el comando egrep, determine qué palabras comienzan con una letra mayúscula
seguida únicamente por vocales. No incluya palabras de una sola letra., (para propósitos de este
ejercicio, considere las vocales como sólo las letras A, E, I, O o U tanto en mayúsculas como en
minúsculas.)
Liste estas palabras, una por línea y clasifíquelas en orden alfabético en el archivo ~/vowel2.txt.
content_view let_
Deliverables A title Question 1
1. Un script llamado ~/bin/ispython, que al ejecutarse con un solo nombre de archivo como
argumento, imprimirá en pantalla 1 si la primera línea del archivo es exactamente #!/usr/bin/
python. De lo contrario, el scripts imprimiría 0 (ayuda: esto puede realizarse combinando los
266
comandos head ygrep).
2. El archivo ~/etcphone.txt, que contiene una lista de todos los archivos en el directorio /etc
(no en subdirectorios) que contienen el patrón 1-###-###-####, donde cada # se remplaza
por un número digital. Los archivos deberían listarse como referencias absolutas, una por
línea en orden alfabético.
3. Los archivos ~/newsitems.txt, ~/newsitems23.txt, ~/newsitems2.txt y ~/newsitems3.txt, cada
uno de los cuales contiene un solo número como su única palabra. El número debería ser
la respuesta a la pregunta respectiva acerca del archivo /usr/share/doc/bash-*/NEWS en el
cuadro anterior.
4. El archivo ~/vowel2.txt, que contiene un listado clasificado en orden alfabético de todas las
palabras en /usr/share/dict/words que comienzan con una mayúscula y seguidas de solo
vocales (excluya las palabras de una sola letra).
267
Ordenando todo: sort y uniq
Conceptos clave
Discussion
En cuadernos anteriores hemos presentado el comando sort en su forma más sencilla: una
herramienta para ordenarr las líneas de un archivo o salida desde un comando en orden alfabético.
Esta lección presentará el comando sort en más detalle.
El comando sort
Clasificación básica
En su forma más simple, el comando sort clasificará en orden alfabético líneas (incluyendo
cualquier espacio en blanco o caracteres de control hallados). El comando sort utiliza la definición
local de locale (definición de lenguaje) para determinar el orden de caracteres (conocido como
orden de recopilación). En el siguiente ejemplo, madonna muestra primero el contenido del archivo
/etc/sysconfig/mouse tal como está, y luego, clasifica el contenido del archivo en orden alfabético.
Si se llama con argumentos, los argumentos se interpretan (en lo posible) como nombres de
archivos para ser clasificados. Si se llama sin argumento, el comando sort clasificará lo que lea de
la entrada estándar.
268
Por defecto, el comando sort clasifica líneas en orden alfabético. El siguiente cuadro lista las
opciones que pueden utilizarse para modificar el orden de clasificación predeterminado.
Opción Efecto
-b, --ignore-leading-blanks Ignora espacios y tabulaciones al comienzo de una línea.
-d, --dictionary-order Considere solamente los caracteres en blanco y los alfanuméricos.
-f, --ignore-case Trate a todos los caracteres como mayúsculas.
-g, --general-numeric-sort Compare palabras como números de punto flotante.
n, --numeric-sort Compare palabras como números enteros.
-r, --reverse Clasifique en orden descendente en vez de en orden ascendente.
A manera de ejemplo, madonna está examinando los tamaños de archivo de todos los archivos
que comienzan por unam en el directorio /var/log.
Sin habérsele dicho, el comando sort clasificó las líneas en orden alfabético (con 1.952 saliendo
antes de 20). Al darse cuenta que esto no era lo que buscaba, madonna agrega la opción -n.
269
[madonna@station madonna]$ ls -s /var/log/m* | sort -n
4 /var/log/messages
20 /var/log/maillog
216 /var/log/messages.3
384 /var/log/messages.1
560 /var/log/messages.4
636 /var/log/messages.2
1236 /var/log/maillog.4
1552 /var/log/maillog.2
1952 /var/log/maillog.3
3104 /var/log/maillog.1
Mejor pero madonna preferiría invertir el orden para que los archivos más grandes estén primero.
Agrega la opción -r.
¿Por qué la opción -1 fue dada al comando ls en el primer ejemplo, pero no en los otros? Por
defecto, cuando el comando ls está utilizando una terminal para la salida estándar, éste
agrupará los nombres de archivo en múltiples comandos para una lectura fácil. Sin embargo,
cuando el comando ls está utilizando una tubería o archivo para salida estándar, imprimirá
los archivos, uno por cada línea. La opción también fuerza esta conducta para la salida de la
terminal.
En los ejemplos anteriores, el comando sort realizó su clasificación con base en los primeros
caracteres buscados en una línea. A menudo, la información formateada no se arregla de modo tan
conveniente. Afortunadamente, el comando sort permite a los usuarios especificar qué columna de
datos tabulares utilizar para determinar el tipo de orden o de un modo más formal, qué columna
debería utilizarse como la tecla de clasificación.
Opción Efecto
-k, --key=POS Utilice la tecla en POS para determinar el orden de clasificación.
-t, --field- Utilice el caracter o caracteres SEP para separar campos (en lugar de un
270
separator=SEP espacio en blanco).
A manera de ejemplo, suponga que madonna quisiera volver a examinar sus archivos de registro
utilizando el formato largo del comando ls. Ella trata simplemente de clasificar su salida de modo
numérico.
Ahora que los tamaños ya no se reportan al comienzo de la línea, se le dificulta. En su lugar, repite
la clasificación con la opción -k para ordenar su salida por la quinta columna obteniendo la salida
esperada.
Luego, madonna está examinando el archivo /etc/fdprm, el cual presenta parámetros de formato a
nivel bajo para los controladores de disquete. Utiliza el comando grep para extraer la información
del archivo, eliminando los comentarios y las líneas en blanco.
271
[madonna@station madonna]$ grep "^[[:alnum:]]" /etc/fdprm
360/360 720 9 2 40 0 0x2A 0x02 0xDF 0x50
1200/1200 2400 15 2 80 0 0x1B 0x00 0xDF 0x54
360/720 720 9 2 40 1 0x2A 0x02 0xDF 0x50
720/720 1440 9 2 80 0 0x2A 0x02 0xDF 0x50
720/1440 1440 9 2 80 0 0x2A 0x02 0xDF 0x50
360/1200 720 9 2 40 1 0x23 0x01 0xDF 0x50
720/1200 1440 9 2 80 0 0x23 0x01 0xDF 0x50
1440/1440 2880 18 2 80 0 0x1B 0x00 0xCF 0x6C
1440/1200 2880 18 2 80 0 ???? ???? ???? ???? # ?????
1680/1440 3360 21 2 80 0 0x0C 0x00 0xCF 0x6C # ?????
cbm1581 1600 10 2 80 2 0x2A 0x02 0xDF 0x2E
800/720 1600 10 2 80 0 0x2A 0x02 0xDF 0x2E
Luego clasifica los datos en forma numérica utilizando la quinta columna como su tecla.
La información ha sido clasificada con éxito utilizando la quinta columna, con los formatos que
especifican 40 pistas agrupadas en la parte superior y 80 pistas agrupadas en la parte inferior. Sin
embargo, dentro de estos grupos madonna desearía clasificar la información por la tercera
columna. Ella agrega una opción adicional -k al comandosort especificando la tercera columna
como su tecla secundaria.
272
Ahora que los datos han sido clasificados por la quinta columna. Para filas con columnas quintas
idénticas, la tercera columna se ha utilizado para determinar el orden final. Un número arbitrario de
teclas puede especificarse al agregar más opciones -k.
Los ejemplos anteriores han demostrado cómo clasificar información con un campo especificado
como una tecla de clasificación. En todos los ejemplos, los campos se separaron por un espacio en
blanco (i.e., una serie de espacios o tabulaciones). Examine, el ejemplo del archivo /etc/passwd.
Las líneas están estructuradas en siete campos cada una, pero los campos están separados con
un “:” en lugar de espacios en blanco. Con la opción -t se puede dar instrucciones al comando sort
para utilizar algún caracter especificado (tal como “:”) para separar campos.
A continuación, madonna utiliza el comando sort con la opción -t para clasificar las primeras 10
líneas del archivo /etc/passwd por el directorio de inicio (el sexto campo).
La usuaria bin, con un directorio de inicio de /bin, está ahora en la parte superior y la usuaria mail
con un directorio de inicio de /var/spool/mail, está en la parte inferior.
Resumen
En resumen, hemos visto que el comando sort puede utilizarse para clasificar datos estructurados,
mediante la opción -k para especificar el campo de clasificación(quizás más de una vez) y la
opción -t para especificar el delimitador del campo.
273
La opción -k puede recibir argumentos más sofisticados, los cuales sirven para especificar
posiciones de caracteres dentro de un campo o personalizar opciones de clasificación para campos
individuales. Ver la página de manual sort(1) para mayor información.
El comando uniq
El programa uniq se utiliza para identificar, contar o suprimir registros duplicados en la información
clasificada. Si se dan argumentos de línea de comandos, se interpretan como nombres de archivo
para los archivo en los cuales operar. Si no se proporcionan argumentos, el comandouniq opera
en la entrada estándar. Dado que el comando uniq sólo funciona en información ya clasificada,
casi siempre se utiliza junto con el comandosort.
-c, --count Línea prefijo con el número de sus ocurrencias, esta es la longitud
de“run”.
-d, --repeated Imprime en pantalla sólo las líneas duplicadas.
-f, --skip-fields=n Evita comparar los primeros campos n, delimitados por un espacio en
blanco.
-i, --ignore-case Ignora mayúsculas o minúsculas
-s, --skip-charsn Salta los primeros n caracteres.
-u, --unique Imprime sólo líneas únicas.
-w, --check- No compara más de n caracteres en cada línea.
chars=n
Para poder entender el comportamiento del comando uniq, necesitamos datos repetitivos en los
cuales operar. El siguiente script python simula el lanzamiento de tres dados de seis caras, al
escribir la suma de 100 funciones una por línea. La usuaria madonna hace el script ejecutable y
luego graba la salida en un archivo llamado trial1.
274
Reducción de datos a enteros únicos
Ahora, trial1 quisiera analizar la información. Comienza por clasificar la información y entubar la
salida a través del comando uniq.
Sin ninguna opción el comando uniq ha suprimido entradas reduciendo los datos de 100 a sólo 15
líneas. Fácilmente, madonna observa que la información es razonable: la suma de cada
combinación para los tres dados de seis caras es representada, a excepción de 3. Puesto que sólo
una combinación de dados podría producir una suma de 3 (todos unos), madonna espera que sea
una ocurrencia relativamente poco frecuente.
Una opción particularmente conveniente para el comando uniq es -c o --count. Esto hace que el
comando uniq cuente el número de ocurrencias de un registro particulars anteponiendo el
resultado al registro en la salida.
En el siguiente ejemplo, madonna utiliza el comando uniq para reproducir su salida anterior, esta
vez anteponiendo el número de ocurrencias de cada entrada en el archivo.
275
Como es de esperarse (al menos por un experto en estadísticas), los números más grandes y los
más pequeños tienen relativamente pocas ocurrencias, mientras que los números intermedios se
presentan en mayor cantidad. La primera columna puede sumarse hasta 100 para confirmar que el
comando uniq identifique cada ocurrencia.
Algunas veces, la gente está solo interesada en identificar datos únicos o repetidos. Las opciones -
d y -u permiten al comando hacer justo eso. En el primer caso, madonna identifica las
combinaciones de dados que se presentan sólo una vez. En el segundo caso, identifica las
combinaciones repetidas al menos una vez.
Ejemplos
La usuaria madonna está examinando los procesos que están ejecutándose en su máquina local.
Está familiarizada con el comando ps aux que presenta la información sobre cada proceso en
ejecución.
276
1 USER El usuario propietario del proceso.
2 PID El ID del proceso
3 %CPU Utilización de la CPU relativa del proceso
4 %MEM La utilización relativa de la memoria del proceso
5 VSZ El "tamaño virtual " del proceso o cuánta memoria ha solicitado el
proceso
6 RSS El "tamaño residente" del proceso o cuánta memoria real está
consumiendo.
La usuaria madonna desearía ordenar los procesos en términos de algunos de estos parámetros.
Primero, ordena los procesos por tamaño de memoria virtual, clasificándolos en orden numérico y
listándolos en orden descendente. Observe el uso del comando tail +2 para suprimir el
encabezado de la lista de procesos.
Luego, madonna clasifica la salida por la sexta columna, que presenta los tamaños de los procesos
residentes en la memoria.
Curiosamente una colección de procesos ocupa la parte superior de la lista incluyendo el servidor
X y varias instancias del demonio sshd (que implementa el servicio de Secure Shell). Se presume
que estos son los procesos activos en el momento.
277
Luego, madonna clasifica por la tercera columna, la actividad relativa de laCPU.
Su máquina no está viendo mucha actividad actual, a excepción de tres procesos diferentes cat
que parecen dividir de modo uniforme su CPU.
Tag Especifica
cmd El nombre corto del comando
pid El ID del proceso
estado El estado actual del proceso (R=en ejecución, S=dormido)
user El usuario propietario del proceso
Como algunos ejemplos al utilizar la opción -o, madonna presenta los procesos con su propio ID de
proceso, el usuario propietario del proceso y el comando ejecutándose.
278
Luego, hace un cuadro del id del proceso y el estado.
Ahora que se ha familiarizado un poco con el comando ps y la opción -o, está lista para comenzar
a hacer algunas preguntas. Primero desea saber quién está ejecutando procesos en la máquina y
cuántos procesos están ejecutándose, listando únicamente el nombre de usuario propietario del
proceso. Luego pasa la salida a través de sort y uniq -c. Observe de nuevo el uso del comando
tail +2 para eliminar el encabezado desde la salida del comando ps.
Ella preferiría que la salida fuera clasificada por lo tanto agrega uno o más sort al final de la
tubería.
Ahora blondie ve con facilidad que el root y apache están ejecutando la mayor parte de los
procesos (presumiblemente demonios en segundo plano), seguidos por madonna, elvis, y blondie
(presumiblemente usuarios interactivos). ¿Cuántos de estos proceso están ejecutándose y cuántos
279
están dormidos? Mediante un truco similar, pero esta vez listando el estado de los procesos del
usuario propietario, ella sale con esta respuesta.
La mayoría de los procesos en su máquina (73) están durmiendo, mientras que relativamente
pocos (5) están ejecutándose (lo que implica que están utilizando la CPU de modo activo).
Ejercicios en línea Lab Exercise Objetivo: Utilizar sort y uniq para administrar informacion de
modo eficiente. Tiempo estimado: 45 minutos.
Especificaciones
2. El archivo /proc/modules lista los módulos cargados en el kernel junto con el tamaño del
módulo (la segunda columna) y un uso de conteo actual (tercera columna).
Utilice el comando para listar los permisos en todos los archivos (y directorios, etc) en el directorio /
etc/ (pero no en subdirectorios). Utilice los comandos sort y uniq para reducir esta información a
un sencillo cuadro, con la primera para el número de veces que se presenta el modo octal
especificado en la segunda columna. El cuadro debería clasificarse en orden numérico
280
descendente, utilizando el número de ocurrencias (la primera columna) como su tecla primaria.
Almacene el cuadro en un archivo recién creado llamado ~/etcmodes.txt.
Si se ha completado correctamente, su cuadro debería tener una forma parecida a la siguiente (no
se preocupe si los valores reales del cuadro difieren).
5. El comando df lista las particiones de disco montadas actualmente junto con uso actual del
disco. La cuarta columna de esta salida del comando lista la cantidad de espacio
disponible en bloques.
Crea un script ejecutable llamado ~/bin/avail. Cuando sea ejecutado el script debería listar
las particiones disponibles (la salida del comando df), clasificada en orden numérico
descendente. La línea del encabezado generada a partir del comando df debería
eliminarse de la salida.
content_view let_
Deliverables A title Question 1
Si ha realizado los ejercicios correctamente, debería poder generar salida similar a la siguiente. No
se preocupe si sus valores actuales difieren.
281
282
Extraer y reunir texto: cut y paste
Conceptos clave
Discussion
En esta lección, exploramos dos comandos utilizados para extraer columnas de un flujo de texto, o
reunir columnas en un flujo más ancho: cut y paste.
El comando cut
El comando cut extrae columnas de texto desde un archivo de texto o flujo. Imagine que toma una
hoja de papel que lista filas de nombres, direcciones de correo-e y números telefónicos. Rasgue la
página verticalmente dos veces para que cada columna sea un pedazo separado. Quédese con la
parte del medio que contiene las direcciones de correo-e y bote las otras dos. Esta es la
mentalidad detrás del cut.
El comando cut interpreta cualquier argumento de línea de comandos como nombres de archivo
en los cuales operan u opera el flujo de entrada estándar si ninguno es provisto. Para especificar
cuáles bytes, caracteres, o campos se cortan, el comando cut debe llamarse con una de las
siguientes opciones.
Opción Efecto
-b Extrae bytes especificados en lista
lista
-c Extrae caracteres especificados en lista
lista
-f lista Extrae campos especificados en lista
Los argumentos de listado son en realidad una lista separada por comas de intervalos. Cada
intervalo puede tomar una de las siguientes formas.
283
Con la opción -c, la list especifica una posición de caracter en una línea de texto, donde el primer
caracter es el primer caracter número 1. A manera de ejemplo, el archivo /proc/interrupts lista
controladores de dispositivo, la solicitud de interrupción (IRQ) a la cual se añaden y el número de
interrupciones ocurridas en la línea IRQ, (no se preocupe si no está familiarizado con los conceptos
de un controlador de dispositivo o línea IRQ. Enfóquese en la manera como cut se utiliza para
manipular la información).
Debido a que los caracteres en el archivo se formatean en columnas, el comando cut puede
extraer regiones particulares de interés. Si sólo la línea IRQ y los números de interrupciones fueran
de interés, el resto del archivo podría ser cut, como en el siguiente ejemplo (observe el uso del
comando grep para reducir primero el archivo únicamente a las líneas pertenecientes a líneas de
interrupción.)
De forma alterna, si únicamente los controladores de dispositivos se unen a líneas IRC de interés
particulares, podrían especificarse intervalos múltiples de caracteres.
284
[student@rosemont student]$ grep '[[:digit:]]:' /proc/interrupts | cut
-c1-5,34-
0: timer
1: keyboard
2: cascade
3: ehci-hcd
5: usb-uhci, ohci1394
8: rtc
10: usb-uhci, eth1
11: usb-uhci, eth0, Audigy
12: PS/2 Mouse
14: ide0
15: ide1
La respuesta es no. El texto aparecerá sólo una vez, en el mismo orden de aparición en la fuente,
incluso si las especificaciones de intervalos están superponiéndose o reordenanándose.
El comando cut también sirve para extraer texto que no está estructurado por la posición de
caracteres, sino por un caracter delimitador tal como un TABULADOR o “:”. Las siguientes
opciones pueden utilizarse para clasificar lo que se conoce como un campo o para líneas de fuente
más selectivas.
Opción Efecto
-d DELIM Utilice DELIM para separar campos en entrada en lugar del
caracter por defectoTAB.
-s No incluya líneas que no contengan el caracter delimitador (útil
para eliminar comentarios y encabezados).
--delimitador de En salida, utilice el texto especificado por CADENA DE TEXTO
salida=CADENA DE TEXTO en lugar del delimitador de campo.
Por ejemplo, el archivo /usr/share/hwdata/pcitable lista más de 3000 IDS de vendedores IDS de
dispositivos (que pueden ensayarse desde dispositivos PCI) y los módulos de kernel y cadenas de
texto que deberían asociarse con ellos, separados por tabulaciones.
285
[student@rosemont hwdata]$ head -15 pcitable
# This file is automatically generated from isys/pci. Edit
# it by hand to change a driver mapping. Other changes will
# be lost at the next merge - you have been warned.
# Edit by hand to change a driver mapping. Changes to descriptions
# will be lost at the next merge - you have been warned.
# If you run makeids, please make sure no entries are lost.
# The format is ("%d\t%d\t%s\t"%s"\n", vendid, devid, moduleName,
cardDescription)
# or ("%d\t%d\t%d\t%d\t%s\t"%s"\n", vendid, devid, subvendid, subdevid,
moduleName, cardDescription)
El siguiente ejemplo extrae la tercera y cuarta columna con el caracter por defecto TABULADOR
para separar campos. Observe el uso de la opción -s, elimina las líneas de encabezado (que no
contienen ningún TABULADOR).
Otro ejemplo, suponga que quisiéramos obtener un listado de los módulos del kernel más
referenciados en el archivo. Podríamos utilizar un comando similar a cut junto con trucos
aprendidos en la última lección para obtener un listado rápido de la frecuencia de aparición de cada
módulo de kernel.
286
Muchas de las entradas obviamente se desconocen o se ignoran intencionalmente, pero sí vemos
que el controlador SCSI aic7xxx y el controlador de tarjeta Ethernet e100 se utilizan con mucha
frecuencia.
La opción -b sirve para especificar qué texto extraer por bytes. Al extraer texto con la opción -b es
muy parecido en espíritu al uso de -c. De hecho, cuando se trabaja con un texto codificado
utilizando ASCII o uno de los conjuntos de caracteres ISO 8859 (tales como Latín-1), los dos son
idénticos. Sin embargo, la opción -b difiere de -c, cuando se utilizan conjuntos de caracteres con
codificación de variables de longitud tal como UTF-8 (un conjunto de caracteres estándar en el que
mucha gente converge y el predeterminado en Red Hat Enterprise Linux).
A manera de ejemplo, considere los siguientes tres caracteres en texto alemán: fr. Al utilizar la
codificación UTF-8, los dos caracteres que componen el conjunto de caracteres ASCII, “f” y “r”, son
codificadas en un sólo byte. No obstante, “”, se codifica con dos bytes como se observa en el
comando wc.
Tenemos un byte para cada una de las letras “f y r, un byte para la nueva ldos bytes para .”
Al utilizar cut -c, “” se consideraría como un sólo caracter, pero al utilizar cut -b, “” se tendrían en
cuenta dos bytes, como en el siguiente ejemplo.
La primera vez, el comando cut contó los dos bytes utilizados para codificar “” como un caracter
sencillo, pero la segunda vez, se consideraron dos bytes. Como resultado, el caracter fue "cortado
por la mitad" con el comando y la terminal no pudo mostrarlo correctamente.
Usualmente, cut -c es la forma correcta de utilizar el comando cut y cut -b solo se necesitará para
situaciones técnicas.
Note
El comando paste
287
El comando paste sirve para combinar archivos múltiples en una sola salida. Recuerde cuando
imaginamos el pedazo de papel que listaba filas de nombres, direcciones de correo -e y números
telefónicos. Después de rasgarlo en tres columnas, ¿qué sucedería si pegaramos la primera a la
tercera, dejando un pedazo de papel listando sólo nombres y números telefónicos? Este es el
concepto detrás del comando paste.
Si tuviéramos más de dos archivos, la primera línea de cada archivo se convertiría en la primera
línea de la salida. La segunda línea de salida contendría las dos segundas líneas de cada archivo
de entrada, obtenido en el orden determinado en la línea de comandos. Por conveniencia, el
nombre de archivo - puede suministrarse en la línea de comandos. Para este "archivo", el comando
pastese leería desde la entrada estándar.
Opción Descripción
-d lista Reutiliza caracteres del listado de delimitadores (en lugar del caracter predeterminado
TAB)
-s, Transpone el resultado para que cada línea en el primer archivo se pegue a una sola
--serial línea, cada línea del segundo archivo se pegue a la siguiente línea sencilla, etc.
Ejemplos
En el diseño de un registro de formato libre, los elementos de registro de entrada son identificados
por su posición en la línea, no por la posición de caracter. Se espera que los campos de entrada
sean separados exactamente por un caracter TABULADOR, pero que ningún caracter que
288
aparezca en los elementos de información mismos pueda utilizarse Cada ocurrencia del
delimitador separa un campo.
Nuestro archivo favorito de ejemplo /etc/passwd tiene campos separados exactamente por el
caracter de dos puntos (“:”). El campo 1 es el nombre de cuenta y el campo 7 da el programa de
shell utilizado. Mediante el comando cut podemos imprimir un nuevo archivo con sólo el nombre de
cuenta y el nombre de shell:
Observe que las líneas de salida utilizan los mismos delimitadores de campo que los registros de
entrada. Podemos cambiar eso con la opción --output-delimiter.
289
El comando mount sin argumentos, retorna una lista que muestra los dispositivos montados y los
puntos de montaje junto con el tipo de sistema de archivos y las opciones relevantes de montaje
Observando que las palabras están separadas por espacios sencillos, el comando cut puede
fácilmente utilizarse para extraer fácilmente la tercera y cuarta palabra (que contiene el punto de
montaje y archivos, respectivamente). El comando debe suplirse con la opción -d " ", que le pide
tratar espacios como delimitadores de campo.
[student@station student]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda3 5131108 4502000 368456 93% /
/dev/hda1 124427 26268 91735 23% /boot
none 127616 0 127616 0% /dev/shm
[student@station student]$ df | cut -d" " -f1,5
Filesystem
/dev/hda3
/dev/hda1
none
¿En qué parte de la salida del comando df, se presenta el quinto "campo"? En alguna parte a
medio camino de las primeras dos columnas. El comando cut obedientemente imprime el primer y
quinto campo (vacío).
Infortunadamente, esta es una limitación común del comando cut. Por fortuna, encontraremos
otras técnicas en una lección posterior para superar este inconveniente.
Ejemplos de pegado
290
Nuestro ejemplo inicial mostró el uso común de paste, donde las primeras líneas de todos los
archivos de entrada se concatenan y separan por un caracter delimitador, el proceso luego se
repite para las siguientes líneas. La opción -s pega todas las lineas del archivo de entrada a la
primera línea de salida, luego pega todas las líneas del segundo archivo de salida y así
sucesivamente:
Ejercicios en línea Lab Exercise Objetivo: Utilizar cut y paste para administrar texto. Tiempo
Estimado: 25 minutos.
Especificaciones
1. Utilice el comando cut para extraer un listado de los nombres de usuario y las shells de
inicio desde el archivo /etc/passwd, donde los nombres de usuario resultantes y las shells
de inicio están separadas por un espacio. Clasifique el listado resultante en orden
alfabético ascendente, mediante la shell de inicio como tecla primaria y el nombre de
usuario como tecla secundaria. Almacene el resultado en el archivo recién creado
~/usershells.txt.
2. El archivo /proc/cpuinfo contiene información sobre su CPU del sistema detectado. Utilice
el comando cut para extraer sólo los valores, no los nombres o el“:” utilizado para separar
los nombres de los valores. Almacene el listado de valores resultante en un archivo recién
creado ~/cpuvalues.txt.
3. El archivo /etc/sysconfig/init sirve para definir parámetros que configuran su método de
arranque de la máquina. Los parámetros se definen mediante la misma sintaxis utilizada
por la shell bash, i.e., NAME=value.
4. El siguiente script puede utilizarse para imprimir una serie de 10 números aleatorios.
291
#!/bin/bash
Cree un archivo llamado titles, que contenga las palabras run1, run2, ... run10, una por
línea en cada una de las diez líneas.
Utilice el comando paste para combinar los archivos llamados titles, trial1, trial2, trial3trial4
y trial5, en ese orden, dentro de un archivo llamado trials. Utilice el caracter TABULADOR
predeterminado para separar las columnas.
Si ha completado el ejercicio de laboratorio correctamente, usted debería ser capaz de generar una
salida similar a la siguiente. No se preocupe si algunos de los valores difieren.
292
[student@station student]$ head -4 usershells.txt cpuvalues.txt
initparams.txt titles trial[15] trials
content_view let_
Deliverables A title Question 1
1. El archivo usershells.txt, que contiene un listado de todos los usuarios y shells de inicio
definido en el archivo /etc/passwd, separado por un espacio. Las líneas deberían
clasificarse en orden alfabético ascendente, mediante las shells de inicio como la tecla
primaria y los nombres de usuario como la tecla secundaria.
2. El archivo cpuvalues.txt, que lista los valores para parámetros buscados en el archivo /proc/
cpuinfo, uno por línea. Los valores deberían aparecer en el mismo orden de aparición en el
293
archivo /proc/cpuinfo.
3. El archivo initparams.txt que contiene un listado en orden alfabético ascendente del
parámetro nombres hallado en el archivo /etc/sysconfig/init.
4. Cinco archivos llamados ~/trial1, ~/trial2, ... ~/trial5 que listan 10 números enteros
aleatorios, uno por línea.
5. El archivo ~/titles, que contiene las 10 palabras run1, run2, ... run10, una palabra por línea.
6. El archivo trials, que incluye el contenido de seis archivos titles, trial1, ... trial5 pegados en
un sólo archivo mediante el comando paste.
294
Rastreo de diferencias: diff
Conceptos clave
Discussion
El comando diff
El comando diff está diseñado para comparar dos archivos similares, pero no idénticos y que
generen salida que describa exactamente la diferencia. El comando diff es más utilizado para
rastrear cambios a archivos de texto tales como informes, páginas web, scripts de shell o código
fuente C . También las utilidades con el comando diff, para que la versión dada de un archivo y la
salida del comando diff comparándolo con otra versión, el archivo puede actualizarse de modo
automático. El comando más importante es el comando patch.
Recognized arguments:
Options for:
auth: for authentication it provides pam_authenticate() and
pam_setcred() hooks.
Observe que las palabras addressy addresses están mal escritas, blondie se dispone a aplicar
cambios, primero al corregir las palabres mal escritas y en segundo añadiendo una línea
295
registrando sus revisiones. Hace una copia del archivo añadiendo la extensión .orig. Luego hace
sus modificaciones.
Ahora utiliza el comando diff para comparar las dos revisiones del archivo.
Sin ir aún dentro de mucho detalle sobre la sintaxis de diff, vemos que el comando ha identificado
las diferencias entre los dos archivos ejemplificando la esencia del comando diff. El comando diff
es tan utilizado que su salida a menudo se refiere como un sustantivo, como en "Aquí está la
diferencia entre los dos archivos".
El comando diff fue concebido en los primeros días de la comunidad Unix. Con el tiempo, se han
hecho mejoras en la manera que diff anota los cambios. Para preservar la compatibilidad de
segundo plano, todavía están disponibles formatos más antiguos. A continuación se listan los
formatos diff más utilizados.
diff"estándar"
No obstante, pronto se tuvieron que hacer algunas mejoras. ¿Qué sucedería si los cambios
se aplicaran dos veces? El editor de comando ed haría los cambios corrompiendo el
contenido del archivo. La solución es un contexto sensible a diff.
296
[blondie@station blondie]$ diff -c README.pam_ftp.orig README.pam_ftp
*** README.pam_ftp.orig 2003-10-07 15:30:05.000000000 -0400
--- README.pam_ftp 2003-10-07 15:30:17.000000000 -0400
***************
*** 8,18 ****
Options for:
auth: for authentication it provides pam_authenticate() and
pam_setcred() hooks.
Options for:
auth: for authentication it provides pam_authenticate() and
pam_setcred() hooks.
Es obvio que, el contexto diff incluye varias líneas alrededor antes de identificar cambios.
Los cambios son anotados al utilizar un “!” para marcar líneas que se han cambiado, “+”
para marcar líneas que se han añadido y “-” para marcar líneas que se han suprimido. Al
utilizar un contenidodiff, las utilidades detectan automáticamente cuando un administrador
trata de actualizar un archivo dos veces.
297
[blondie@station blondie]$ diff -u README.pam_ftp.orig README.pam_ftp
Options for:
auth: for authentication it provides pam_authenticate() and
pam_setcred() hooks.
En lugar de identificar una línea como "cambiada", el comando unificadodiff anota que la
versión original debería borrarse y que debería agregarse la nueva versión.
Se supone que los tres formatos anteriores eran fáciles de leer por alguna otra utilidad tal
como el editor -W80 o la utilidad patch. En contraste, el formato "lado a lado" está
diseñado para ser leído por humanos. Como su nombre lo indica, las dos versiones del
archivo se muestran diff lado a lado, con anotaciones en el medio que ayudan a identificar
cambios. El siguiente ejemplo pide un diff"lado a lado" mediante la opción -y y más
adelante, clasifica lo que la salida debería formatear en las 80 columnas con -W80.
298
Aunque la salida sería más efectiva utilizando una terminal ancha, ofrece una idea intuitiva
para las diferencias entre los dos archivos.
El comando diff silecioso apenas informa si dos archivos difieren, no la naturaleza de las
diferencias.
Este formato genera diferencias mediante una sintaxis reconocida por el pre-procesador
cpp. Éste permite ya sea a la versión original como al la nueva ser incluidas al definir la
etiqueta especificada. Aunque esto está más allá del alcance de este curso es incluído
para beneficio de aquellos familiarizados con el preprocesadorcpp C.
También existen otros formatos de salida menos utilizados. ¿Qué formato es el correcto? La
respuesta depende de las preferencias del generador "diff" o de las expectativas de quien pueda
estar recibiendo el "diff". El comando diff sirve para comunicar sugerencias a la comunidad de
código abierto sobre cambios al código abierto de algún programa, con el fin de corregir un error o
agregar una característica. En este contexto, casi siempre se prefiere el formato unificado diff.
El siguiente cuadro resume algunas de las opciones que pueden utilizarse para especificar el
formato de salida para el comando diff.
Opción Efecto
-c Generar el contexto de formato sensible
-C, Generar un formato de contexto sensible mediante N líneas de contexto, si se
--context[=N] especifican.
-u Generar el formato unificado
-U, --unified[=N] Generar el formato unificado mediante contexto de líneas, si se especifican.
-N Otro formato para especificar líneas de contexto N. Sólo utilizadas con -c o -u.
-y, --side-by- Generar el formato lado a lado
side
-W, --width=N Usa las columnas Nal generar el formato lado a lado
--left-column Imprime sólo la columna izquierda cuando usa el formato lado a lado.
-q, --brief Solo reporta si los archivos difieren, no los detalles de la diferencia.
El comando diff espera ser llamado con dos argumentos, uno desde- archivo y otro al-archivo (o
en otras palabras, un archivoviejo y un archivonuevo). La salida del comando diff describe lo que
se debe hacer al desde-archivo para crear el al-archivo.
299
Si uno de los nombres de archivo se refiere a un archivo regular y el otro a un directorio, el
comando diff buscará un archivo con el mismo nombre en el directorio especificado. Si ambos son
directorios, el comando diff comparará archivos en ambos directorios, pero no buscará de modo
recursivo en los subdirectorios (a menos que la opción -r sea especificada, ver abajo).
Adicionalmente, el nombre de archivo especial“-” hará que el comando diff lea desde la entrada
estándar en lugar de un archivo regular.
Opción Efecto
-b, -w, --ignore-all-space Ignora el espacio en blanco al comparar líneas.
-B, --ignore-blank-lines Ignora el espacio en blanco al comparar líneas.
-i, --ignore-case Ignora el uso de mayúsculas (i.e., considere caracteres equivalentes
a las mayúsculas y minúsculas).
-I, --ignore-matching- Ignora cambios que insertan o borran líneas coincidentes con el
lines=regex argumento obligatorio regex.
September 2003
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
300
[blondie@station blondie]$ diff cal.txt cal_edited.txt
0a1,4
> ====================
> ==== This Month ====
> ====================
>
9a14
>
Con la opción -B, sin embargo, el comando diff ignora la línea nueva, vacía en la parte inferior.
Con la opción -I se puede pedirle al comando diff ignorar las líneas que comienzan por “=”.
El comando diff puede actuar de modo recursivo, bajando dos árboles de directorio siimilares y
anotando las diferencias. El siguiente cuadro lista las opciones importantes para la conducta
recursiva de diff.
Opción Efecto
-r, --recursive Al comparar directorios, busque también de modo recursivo a través de
subdirectorios.
-x, Al comparar directorios de modo recursivo, omita los nombres de archivo
--exclude=patrón coincidentes patrón.
-X, --exclude- Al comparar directorio de modo recursivo, omita los nombres de archivos
from=file coincidentes con patrones especificados en file.
A manera de ejemplo, blondie está examinando dos versiones de un proyecto llamado vreader. El
proyecto involucra scripts Python que convierten la información de calendario del formato vcal a un
formato XML. Ella ha descargado dos versiones de un proyecto, vreader-1.2.tar.gz y
vreader-1.3.tar.gz y ha expandido cada uno de los archivos en su directorio de inicio local.
[blondie@station blondie]$ ls
vreader-1.2 vreader-1.2.tar.gz vreader-1.3 vreader-1.3.tar.gz
301
vreader-1.2/
|-- addressbook.vcard
|-- calendar.ics
|-- conv_db.py
|-- conv_db.pyc
|-- datebook.xml
|-- templates/
| `-- datebook.xml
`-- vreader.py
vreader-1.3/
|-- addressbook.vcard
|-- calendar.ics
|-- conv_db.py
|-- conv_db.pyc
|-- datebook.out.xml
|-- datebook.xml
|-- templates/
| `-- datebook.xml
`-- vreader.py
Para resumir las diferencias entre las dos versiones, ella ejecuta diff de modo recursivo en los dos
directorios.
El comando diff busca de modo recursivo a través de los dos directorios y observa las siguientes
diferencias.
302
A menudo, cuando comparamos los árboles de directorio más complicados se espera que haya
archivos que cambien y otros que no. Por ejemplo, el archivo conv_db.pyc es código Python
compilado, automáticamente generado desde el archivo del guión de texto Python conv_db.py.
Dado que blondie no está interesada en las diferencias entre las versiones compiladas del archivo,
utiliza la opción de línea de comando -x para excluir las comparaciones de la forma de archivo. Del
mismo modo, no está interesada en los archivos terminados en -x, así que los especifica con una
opción adicional-x.
Ahora que la salida del comando diff está limitada sólo por el archivo vreader-1.2/vreader.py y su
complemento en vreader-1.3.
Como una alternativa para listar los patrones de archivos a excluir en la línea de comandos, los
patrones pueden recopilarse en un simple archivo de texto que se especifica en su lugar, mediante
la opción -X. En el siguiente ejemplo blondie ha creado y utiliza tal archivo.
Dado que blondie incluyó *.py en su lista de patrones de archivo para excluir, el comando diff se
abandona sin nada qué decir.
Ejemplos
Después de actualizar su paquete RPM sendmail, blondie observa que tiene un nuevo archivo de
configuración en su directorio/etc/mail, sendmail.cf.rpmnew. A ella le gustaría ver cómo se compara
este archivo con su archivo de configuración ya existente, /etc/mail/sendmail.cf. Utiliza diff para
resumir las diferencias.
303
[blondie@station blondie]$ diff /etc/mail/sendmail.cf /etc/mail/sendmail.cf.rpmnew
19,21c19,21
< ##### built by [email protected] on Tue Apr 1 15:09:38 EST 2003
< ##### in /etc/mail
< ##### using /usr/share/sendmail-cf/ as configuration include directory
---
> ##### built by [email protected] on Wed Sep 17 14:45:22 EDT 2003
> ##### in /usr/src/build/308253-i386/BUILD/sendmail-8.12.8/cf/cf
> ##### using ../ as configuration include directory
40d39
<
101c100
< DSnimbus.example.com
---
> DS
Está satisfecha con la nueva versión del archivo de configuración que difiere únicamente en
algunas de las líneas de comentarios y en la falta de una configuración local que ha agregado a su
nueva versión.
El administrador de sistemas de una máquina ha notado que la utilidad useradd crea una copia de
seguridad del archivo /etc/passwd cada vez que le hace un cambio, llamado /etc/passwd-. Como
usuaria root, ella desearía ver el cambio más reciente al archivo /etc/passwd.
Creación de un parche
304
Una vez editada su copia del archivo, quisiera enviar los cambios al coordinador de cambios al
proyecto vreader. En la comunidad de código abierto, esta persona se conoce como el encargado
del proyecto. En lugar de enviar una copia entera de la versión. ella graba las diferencias entre su
versión y el original en un archivo llamado vreader-1.3.blondie.patch.
Ahora envía por correo-e el archivo de corrección al encargado del proyecto, quien puede
fácilmente utilizar un comando llamado patch para aplicar los cambios a una versión original.
Ejercicios en línea Lab Exercise Objetivo: Utilizar el comando diff para rastrear cambios en los
archivos. Estimated Time: 10 mins.
Especificaciones
3. Para su copia local del directorio gedit-2, haga los siguientes cambios.
1. Suprima los dos archivos.
2. Cree un archivo llamado arbitrariamente en algún lugar bajo el directorio gedit-2
con un contenido arbitrario.
3. Usando el editor de texto, borre las tres líneas de cualquier archivo en el directorio
gedit-2/taglist.
content_view let_
Deliverables A title Question 1
305
referencia absoluta.
306
Traducción de texto: tr
Conceptos clave
Discussion
El comando tr
El comando tr es una utilidad muy versátil que realiza traducciones de caracter en flujos. Traducir
puede suponer sustituir un caracter por otro, borrar caracteres o "comprimirlos" (contrayendo
secuencias repetidas de un caracter en uno). Cada uno de estos usos será descrito en las
siguientes secciones.
Sintaxis Efecto
tr SET1 SET2 Substituye los caracteres especificados en SET2 para los caracteres
complementarios especificados en SET1.
tr -d Borra todos los caracteres especificados en CONJUNTO.
CONJUNTO
tr -s Comprime todos los caracteres especificados en CONJUNTO.
CONJUNTO
tr -s SET1 Primero, sustituya todos los caracteres hallados en SET2 por los caracteres
SET2 complementarios en SET1 luego, comprima todos los caracteres encontrados en
SET2.
tr -ds SET1 Primero borre todos los caracteres hallados en SET1, luego comprima todos los
SET2 caracteres en SET2.
Especificación de caracter
Como el cuadro anterior lo ilustra, el comando tr hace uso extensivo de caracteres definidos en
conjuntos. La sintaxis para definir un intervalo de caracteres basados en el especificador de
intervalo hallado en expresiones regulares. Las siguientes expresiones pueden utilizarse al
especificar caracteres.
Sintaxis Caracter(es)
307
literal La mayoría de los caracteres coinciden con una traducción literal de ellos mismos.
\n El caracter de nueva línea.
\r El caracter de entrada.
\t El caracter de tabulación (horizontal).
\\ El caracter \ .
[A-Z] El intervalo de caracteres delimitados por los caracteres especificados. Depreciado,
porque el orden en que se determina el intervalo depende del conjunto de caracteres
utilizados para codificar la información.
[:alnum:] Todas las letras y dígitos.
[:alpha:] Todas las letras.
[:blank:] Todos los espacios horizontales en blanco.
[:digit:] Todos los dígitos.
[:lower:] Todos los caracteres en minúsculas.
[:print:] Todos los caracteres imprimibles.
[:punct:] Todos los caracteres de puntuación.
[:space:] Todos los espacios horizontales o verticales en blanco.
[:upper:] Todos los caracteres en mayúsculas.
El cuadro no presenta una lista completa. Para mayor información, consulte la página de manual
tr(1) o tr --help.
A menos que se haya solicitado lo contrario (mediante opciones), el comando espera ser llamado
con dos argumentos, cada uno de los cuales especifica un intervalo de caracteres. Para cada uno
de los caracteres especificados en el primer conjunto, lo sustituirá el caracter encontrado en la
misma posición en el segundo conjunto. Considere el siguiente ejemplo trivial.
Observe que en la salida, el caracter “d” es remplazado por el caracter “z”, “e” es remplazado por el
caracter “y”, y “f” es remplazado por el caracter “x”. El orden de los conjuntos es importante. La
tercera letra del primer conjunto es remplazada por la tercera letra del segundo conjunto.
¿Qué sucede si las longitudes de los dos conjuntos son desiguales? El segundo conjunto se
extiende a la longitud del primer conjunto al copiar el último caracter.
Un ejemplo clásico del comando es traducir todo el texto en letras mayúsculas o todo en
minúsculas. La sintaxis de la "vieja escuela" para dicha traducción utilizaría intervalos de caracter.
308
[madonna@rosemont madonna]$ cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost rha-server
192.168.0.254 rosemont.example.com rosemont
192.168.0.51 hedwig.example.com hedwig h
192.168.129.201 z
[madonna@rosemont madonna]$ tr a-z A-Z < /etc/hosts
# DO NOT REMOVE THE FOLLOWING LINE, OR VARIOUS PROGRAMS
# THAT REQUIRE NETWORK FUNCTIONALITY WILL FAIL.
127.0.0.1 LOCALHOST.LOCALDOMAIN LOCALHOST RHA-SERVER
192.168.0.254 ROSEMONT.EXAMPLE.COM ROSEMONT
192.168.0.51 HEDWIG.EXAMPLE.COM HEDWIG H
192.168.129.201 Z
Si recordamos que el orden de intervalos de caracteres es importante para el comando tr, las
clases de caracteres necesitarían generar consistentemente intervalos ordenados. Únicamente las
clases de caracter [:minúscula:] y [:mayúscula:] están garantizadas para hacerlo, lo que implica que
son las únicas clases apropiadas cuando se utiliza tr para la traducción de caracteres.
Cuando se invoca con la opción -d, el comando tr adopta una conducta radical diferente. El
comando tr ahora espera un único argumento (opuesto a dos, arriba), el cual establece otra vez
una serie de caracteres. El comando tr filtrará entonces el flujo de entrada estándar, borrando cada
uno de los caracteres especificados, escribiéndolo en la salida estándar.
En el primer caso, se borraron los caracteres literales especificados “d”, “e” y “f”. En el segundo
caso, fueron borrados todos los caracteres pertenecientes a las clases de caracteres [:punct:] o
[:upper:].
309
Uso de tr para comprimir caracteres
Al utilizar la opción -s, el comando tr puede utilizarse para comprimir un conjunto continuo de
caracteres en un caracter sencillo. Si es llamado sin argumentos el comando tr simplemente
comprimirá el conjunto específico de caracteres como en el siguiente ejemplo.
Observe que esto es en esencia los mismo que realizar la operación dos por separado.
Por último, el comando tr se puede llamar con las opciones -s y -d. En este caso, el comando tr
espera dos argumentos. El comando tr borrará el primer conjunto de caracteres y luego comprimirá
el segundo conjunto.
Conjuntos complementarios
Aparte de -s y -d, hay dos opciones que modifican la conducta de tr, presentadas a continuación.
Opción Efecto
310
-c, Complemento SET1 antes de operar (i.e., uso del conjunto de caracteres
--complement excluídos por SET1)
-t, --truncate- Trunca la longitud de SET1 a la de SET2 antes de operar.
set1
Como un ejemplo rápido de la opción -c, el siguiente borra desde la entrada estándar cada caracter
que no sea vocal o espacio en blanco.
Una nota final antes de dejar nuestras “aes” y “es” y dirigirnos a ejemplos más prácticos.
En algunos de los ejemplos anteriores, madonna tuvo el cuidado de proteger expresiones tales
como [:punct:] con comillas sencillas, pero en algunas veces no lo fue. Cuando no las protegió,
tuvo suerte. Considere la siguiente secuencia.
¿Por qué razón madonna obtuvo dos resultados muy diferentes de la misma línea de comando? Si
no sabe la respuesta, e incluso si la sabe, debería proteger argumentos al comando tr con
comillas.
Ejemplos
Recuerde unas pocas lecciones atrás, cuando describíamos el comando cut y su capacidad para
extraer campos de texto de un flujo. Tratamos de utilizar el comando cut para extraer el primer y
quinto campo de la salida del comando df, especificando un espacio como el campo delimitador.
[madonna@station madonna]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda3 5131108 4499548 370908 93% /
/dev/hda1 124427 26268 91735 23% /boot
none 127616 0 127616 0% /dev/shm
[madonna@station madonna]$ df | cut -d" " -f1,5
Filesystem
/dev/hda3
/dev/hda1
none
311
Previamente identificamos el problema con este enfoque. El comando cut no reconoce un conjunto
de espacios como campos separados, sino un conjunto de campos (uno por cada espacio). Con su
nuevo conocimiento del comando tr, madonna sabe cómo resolver el problema.
Ahora, madonna puede utilizar con facilidad el comando tr para extraer las columnas apropiadas.
Tras examinar el archivo, se da cuenta que éste utiliza la convención DOS para separar las líneas
(un retorno de carro/nueva línea) como es ilustrado por la combinación “^M$” cuando se utiliza el
comando cat -A.
Ella preferiría que el texto utilizara la convención Unix (un caracter de una sola palabra new line).
Utiliza el comando tr para borrar todas las instancias del caracter, almacenando el resultado en el
archivo 2city12unix.txt.
Para confirmar que la conversión sucedió correctamente, realiza un par de revisiones. Primero
examina el archivo con cat -A y observa que los caracteres “^M” se han suprimido.
312
[madonna@station madonna]$ head -5 2city12unix.txt | cat -A
The Project Gutenberg Etext of A Tale of Two Cities, by Dickens$
$
Please take a look at the important information in this header.$
We encourage you to keep this file on your own disk, keeping an$
electronic path open for the next readers. Do not remove this.$
En segundo lugar, realiza una conteo de palabras en ambos archivos mediante el comando wc
Ella observa que la diferencia en el número de caracteres en los dos archivos es igual al número
de líneas en los archivos (787603 - 771239 = 16364). Esto es apropiado si el comando tr borra un
caracter por línea, como se espera.
Por último, puesto que ya no está interesada en mantener la versión DOS formateada del archivo,
renombra el archivo 2city12unix.txt como 2city12.txt.
Uso de tr las frecuencias de conteo de palabras Este ejemplo está basado en un ejemplo
similar hallado en (info coreutils) de la página informativa (info coreutils).
La buena escritura suele requerir que los autores eviten el uso en exceso de ciertas palabras
claves. La usuaria madonna utiliza el editor de texto para extraer el párrafo del texto.
Ahora quisiera generar un conteo de la frecuencia con que se utilizan algunas palabras.Para utilizar
el comando uniq -c, madonna desearía reordenar el texto para que las palabras aparezcan una
por línea. Ella traza el siguiente plan.
313
2. Convertir todos los caracteres en letras mayúsculas a letras minúsculas, con el fin de que
It y it sean consideradas como la misma palabra.
3. Convertir cada caracter espacio en un nuevo caracter nueva línea y comprimir múltiples
caracteres nueva línea en uno.
Comienza por implementar su plan paso a paso con el fin de observar los resultados intermedios
En este punto, madonna está lo suficientemente cómoda con sort y uniq para finalizar el proceso.
Motivada por su progreso, repite la técnica en todo el texto (el proceso tomó cerca de 8 segundos
en un procesador 700MHZ).
314
[madonna@station madonna]$ tr -d '[:punct:]' < 2city12.txt | tr
'[:upper:]' '[:lower:]' |
tr -s ' ' '\n' | sort | uniq -c | sort -rn | head -5
8082 the
4967 and
4061 of
3517 to
2952 a
Rot13
En los comienzos de grupos de Usenet, la gente adoptó una convención para oscurecer el texto
llamado rot13. Suponga que usted va a enviar un chiste y quisiera inmediatamente incluir la línea
de remate del chiste, pero no quisiera que dicha línea de remate fuera immediatamente obvia. La
línea de remate se convirtió en la más obvia. Dicha línea pudo ser convertida al rotar cada letra por
13 sitios para que “a” se convirtiera en “n”, “b” se convirtiera en “o”, y “z” se convirtiera en “m”,
como se ilustra en el siguiente ejemplo.
[madonna@station madonna]$ echo "Gb trg gb gur bgure fvqr." | tr A-Za-z N-ZA-Mn-za-m
Para pasar al otro lado.
Ejercicios en línea Lab Exercise Objetivo: Familiarizarse con el comando tr. Estimated Time: 10
mins.
Especificaciones
1. El archivo /etc/passwd usa los dos puntos para delimitar campos. Cree el archivo
~/passwd.tsv, el cual es una copia del archivo /etc/passwd convertido para utilizar
tabulaciones como delimitadores de campo (i.e., cada “:” se convierte en una tabulación).
2. Crear el archivo ~/file_roller.converted que es una copia del archivo /usr/share/file-
roller/glade/file_roller.glade, con las siguientes conversiones.
a. Convertir todas las tabulaciones a espacios.
b. Convertir las comillas dobles (") a comillas sencillas ('). (no utilice acento grave (`).)
3. Cree un archivo llamado ~/openssl.converted, el cual es copia del archivo
/usr/share/ssl/openssl.cnf, con las siguientes conversiones.
a. Todas las líneas de comentarios son suprimidas (líneas cuyo primer caracter de
espacio en blanco es un #).
b. Todas las líneas vacías son suprimidas.
c. Todas las mayúsculas son dobladas en letras minúsculas.
315
d. Todos los dígitos se remplazan por el caracter de subrayado (“_”).
content_view let_
Deliverables A title Question 1
1. El archivo ~/passwd.tsv, el cual es una copia del archivo /etc/passwd con tabulaciones
sustituídas por dos puntos.
2. El archivo ~/file_roller.converted, el cual es una copia del archivo /usr/share/file-roller/glade/
file_roller.glade, con todas las tabulaciones convertidas en espacios y todas las comillas
dobles (") convertidas en comillas sencillas (').
316
Revisión ortográfica: aspell
Conceptos clave
Discussion
En la distribución de Red Hat Enterprise Linux, la utilidad del comando aspell es la utilidad primaria
para revisar la ortografía de los archivos de texto. En esta lección, aprendimos cómo utilizar aspell
para revisar la ortografía del archivo de modo interactivo y personalizar el corrector de ortografía
con un diccionario especial.
Uso de aspell
Comando Acción
-c file, chequear file Realiza una revisión de ortografía en el archivo file.
-l, list Imprime una lista de las palabras mal escritas halladas en el flujo del
entrada estándar.
config Bota la configuración actual aspell a la salida estándar.
dump master|personal| Bota una copia de la lista maestra de palabras, lista personal de
repl palabras y lista personal de remplazo, respectivamente.
create master| Crea la lista maestra de palabras, lista personal de palabras o lista
personal|repl personal de remplazo, respectivamente, entradas de lectura desde la
entrada estándar.
merge master| Fusiona entradas leídas desde la entrada estándar dentro de la lista
personal|repl maestra de palabras, la lista personal de palabras o la lista de
remplazo, respectivamente.
El siguiente cuadro lista algunas de las opciones utilizadas con el comando aspell.
Opción Efecto
-W --ignore=N Ignora palabras de menos de N caracteres, (por defecto, solo se hace
caso omiso a palabras sencillas).
--ignore-case Ignora mayúsculas al realizar comparaciones de palabras.
-p, Utiliza la lista de palabras filename para la lista personal de palabras.
--personal=filename
317
-x, --dont-backup No crea archivo de seguridad al realizar la revisión ortográfica.
El usuario prince ha compuesto el siguiente mensaje, el cual piensa enviar por correo-e al usuario
elvis.
I heard that you were about to take the lab test for the string
procesing workbook in Red Hat Academy. IIRC, its prety
straightforward, if you've been keeping up with the exercises.
LOL, Prince
Antes de enviar el mensaje, prince utiliza aspell -c para realizar una revisión ortográfica interactiva.
Tras la ejecución, el comando aspell abre una sesión interactiva, subrayando la primera palabra
mal escrita.
Hey Elvis!
I heard you were about to take the lab test for the string
Procesing workbook in Red Hat Academy. IIRC, its prety
straightforward, if you've been keeping up with the exercises.
LOL, Prince
=====================================================================
1) processing 6) preceding
2) precessing 7) professing
3) precising 8) promising
4) proceeding 9) proposing
5) prosing
i) Ignore I) Ignore all
r) Replace R) Replace all
a) Add x) Exit
=====================================================================
?
En este momento, prince tiene un teclado "vivo", lo que significa que al pulsar una tecla tendrá
efecto sin necesidad de utilizar la tecla enter. Puede escoger de las siguientes opciones.
318
El comando aspell hará lo mejor posible para sugerir remplazos de palabras mal escritas,
desde su biblioteca. Si ha encontrado una sugerencia correcta (como en este caso), esa
sugerencia puede remplazarse al pulsar la tecla numérica asociada con ésta.
Ignorar la palabra
Si aspell no pudo generar una sugerencia apropiada, prince puede utilizar r para
remplazar manualmente la palabra. Al terminar, aspell volverá a empezar, primero
volviendo a revisar el remplazo especificado. Al utilizar R mayúscula, aspell recordará el
remplazo y automáticamente remplazará otras instancias de la palabra mal escrita.
Si prince deseara que aspell aprendiera una nueva palabra, para que no fuera marcada
cuando se revisen futuros archivos puede pulsar a para agregar la palabra a su directorio
personal.
Salida aspell
Al pulsar x, prince inmediatamente puede salir de la sesión interactiva aspell. Todas las
correcciones de ortografía ya implementadas se almacenarán.
Como prince sigue a través de la sesión interactiva, el comando aspell marca las palabras
procesing, prety, IIRC y LOL como mal escritas. Para estas dos, prince acepta sugerencias de
aspellpara corregir la ortografía. Las últimas dos "palabras"son las abreviaturas más utilizadas por
prince en sus correos-e, por lo tanto, las añade a su directorio. Infortunadamente, debido a que its
es una palabra legítima, aspell no reporta el uso incorrecto por parte de prince.
Al finalizar, prince tiene dos archivos, la versión corregida de toelvis y la copia de seguridad del
original generada automáticamente, toelvis.bak.
[prince@station prince]$ ls
toelvis toelvis.bak
[prince@station prince]$ diff toelvis.bak toelvis
4c4
< processing workbook in Red Hat Academy. IIRC, its prety
---
> processing workbook in Red Hat Academy. IIRC, its pretty
Mediante la opción -l, el comando aspell puede utilizarse para realizar revisiones ortográficas en
un modo interactivo de bash. Utilizado de esta manera, aspell simplemente lee la entrada estándar
y escribe en la salida estándar cada palabra que marcaría como mal escrita.
319
A continuación, suponga que prince realizó una revisión ortográfica no-interactiva antes de ejecutar
la sesiónaspell de modo interactivo.
La utilidad aspell lista cuatro palabras que marcaría como mal deletreadas. Después de la revisión
ortografía interactiva, prince realiza una revisión ortográfica no interactiva en su copia de seguridad
del archivo original.
Puesto que las palabras IIRC y LOL fueron añadidas al diccionario personal de prince, ya no se
marcan como mal escritas.
Por defecto el comando aspell utiliza dos diccionarios al realizar revisiones ortográficas: el sistema
amplio de diccionario maestro y el del diccionario personal del usuario. Cuando prince decide
agregar una palabra, la palabra se almacena en su diccionario personal. Prince utiliza la habilidad
de aspell dump para ver su directorio personal.
Del mismo modo, podría también ver el diccionario maestro del sistema.
El comando aspell puede tambien crear automáticamente un directorio personal (si aún no existe )
o fusionarlo (si existe), mediante palabras leídas desde la entrada estándar. Suponga que prince
tiene un mensaje de correo-e anterior, en el cual utilizó muchas de las abreviaturas más usadas.
Desearía agregar todas las abreviaturas encontradas en ese correo-e a su directorio personal.
Primero extrae las palabras del mensaje original con aspell -l.
320
[prince@station prince]$ aspell -l < good_email.txt
FWIW
AFK
RSN
TTFN
Después de observar los resultados, decide agregar todas estas palabras a su diccionario personal
con aspell merge personal. Cuando termina, vuelve a ver el diccionario personal (expandido).
Getting Help
Es un primer intento razonable por saber, pero en este caso está errado. Al igual que la mayoría de
los comandos aspell generará un resumen de uso cuando se llama con la opción --help. Puede
hallarse documentación adicional en el directorio /usr/share/doc/aspell-0*/man-text/ (como archivos
de texto sencillo) o en formato html. El siguiente comando, ejecutado desde una terminal X, iniciará
prince apagado en la documentación html.
Ejemplos
321
El usuario prince contesta las preguntas relacionadas con la red de servicios de Linux en sus
correos-e y aspell marca de modo sistemático como palabras mal escritas los nombres de servicio
convencionales. Le gustaría agregar a su directorio personal los nombres del servicio hallados en
el archivo /etc/services.
Primeros hace la revisión ortográfica del archivo /etc/services de modo interactivo y almacena los
resultados en ~/services.maybe.
Navegando el archivo una vez más, prince está satisfecho que la lista contenga palabras que
preferiría no haber marcado como mal escritas. Agrega la lista de palabras a su directorio personal.
Para confirmar, hace de nuevo la revisión ortográfica del archivo /etc/services, de modo no
interactivo.
Ejercicios en línea Lab Exercise Objetivo: Utilizar el comando aspell para realizar revisiones
ortográficas de rutina. Estimated Time: 10 mins.
Configuración
Con el fin de prepararse para este ejercicio, suprima todos los diccionarios personales (o la lista de
remplazo) acumulados con el siguiente comando.
Especificaciones
1. Generar una lista de todas las palabras que aspell marque como mal escritas halladas en
todos los archivos bajo el directorio /etc/sysconfig y sus subdirectorios. La lista debería
estar en orden alfabético ascendente y las palabras duplicadas deberían suprimirse.
Almacene la lista (una palabra por línea) en el archivo ~/sysconfig.spell.txt.
Con uso creativo de los comandos find, xargs, cat, sort y uniq, esto puede realizarse en
una línea de comandos.
322
Copie el archivo /usr/share/doc/which-*/README en su directorio de inicio. Realice una revisión
ortográfica interactiva en el archivo con el corrector ortográfico aspell: Aplique las siguientes reglas
a las palabras mal escritas.
a. Agregue las siguientes palabras a su directorio personal: gcc, stdout, texinfo, stdin, usr,
csh
b. Utilice las sugerencias de corrección de aspell: explicity (debería leerse explicitly)
c. De modo manual remplace la palabra Litmaathcon Smith.
d. Ignore todas las otras palabras marcadas.
content_view let_
Deliverables A title Question 1
3. Un directorio personal aspell que contenga exactamente las palabras gcc, stdout, texinfo,
stdin, usr, y csh.
323
Formatear texto (fmt) y dividir archivos (split)
Conceptos clave
Discussion
El comando fmt
Esperemos que las lecciones en este cuaderno hasta el momento hayan demostrado formas de
gran alcance para la manipulación de texto con las utilidades básicas de línea de comandos de
Linux (y Unix). Puesto que Linux provee una caja de herramientas manipuladoras de comandos de
texto tan útiles, los datos que la gente manipula quedan como simple texto. El archivo /etc/passwd
es un ejemplo clásico. En lugar de incrustar definiciones del usuario en alguna base de datos que
requiera una utilidad personalizada para acceder, se definen en un archivo de texto sencillo que
cualquier persona con el conocimiento del comandogrep puede buscar.
El uso común de un editor de texto sencillo sigue como resultado natural de la ocurrencia común
del archivo de texto sencillo. Hacemos énfasis en que los editores de texto no son procesadores de
palabras. Las aplicaciones de procesadores de palabras tales como OpenOffice o AbiWord,
generalmente almacenan información mediante formateo de marcas o binario para definir fuente,
colores y otros aspectos de la apariencia del texto. En contraste, los editores sencillos de texto,
tales como nano, vim o gedit, almacenan solamente la información: lo que usted ve es lo que
obtiene. Como resultado, los usuarios utilizan editores de texto para modificar archivos de texto con
mucho más control y previsibilidad.
324
Figure 1. Manejo de texto mediante gedit
325
Figure 4. Manejo de texto utilizando nano
¿Qué resultado muestra wc? Las cuatro aplicaciones usaron cuatro convenciones diferentes para
mostrar y almacenar la oración de texto sencilla (cinco, si usted incluye el formato binario
OpenOffice).
El editor de texto nano fue la única aplicación que implementó delimitación de palabra por defecto.
Aunque elvis nunca pulsó la tecla enter, se insertaron tres líneas nuevas de caracteres ASCII. Las
aplicaciones gedit ygvim fueron consistentes con la convención de Linux (y Unix): no insertaron
caracteres de línea nueva en medio del texto, pero no permitirían que un archivo de texto terminara
sin un caracter de línea nueva interrumpida. Aunque es consistente con el otro en términos de
326
cómo fue almacenado el archivo, difieren en la manera como el texto fue presentado al usuario:
gedit delimitó el texto con delimitadores de palabras, mientras que gvim delimitó el texto
únicamente cuando no pudo entrar ninguno más en una línea. Al igual que gedit, la aplicación de
OpenOffice delimitó el texto mientras lo visualizaba, pero no agrego la línea nueva convencional de
Linux al final del archivo cuando lo guardaba en el disco. No podemos ni siquiera comenzar a
discutir las razones por las cuales el formato estándar de OpenOffice necesitó cerca de 5.000 bytes
de datos binarios para almacenar cerca de 200 caracteres.
Todo esto es para decir que la forma como una aplicación maneja los problemas de delimitación de
palabra no es obvia para el usuario casual, y a menudo, cuando se lee el texto con una utilidad que
sea escrita por otra, los aspectos de delimitación de palabras pueden causar problemas.
El comando fmt se utiliza para delimitar texto, insertando nuevas líneas en límites de palabras para
crear líneas de una longitud especificada por defecto (75 caracteres). A manera de ejemplo,
considere cómo el comando fmt reformatea el archivo side_effect.gedit.
El comando cat, fiel a su naturaleza, no realizó ningún formato en el archivo cuando lo visualizó. El
hecho que las líneas delimitadas a 80 caracteres es un efecto secundario de la terminal que lo
estaba mostrando. Por otra parte, el comando fmt delimitó el texto en limitadores de palabras para
que ninguna línea tenga más de 75 caracteres de longitud.
Al igual que la mayoría de los comandos de procesador de texto encontrados en este cuaderno, el
comando fmt interpreta argumentos como nombres de archivos en los cuales operar, u operar en
entrada estándar si ninguno es provisto. Su salida se escribe a la salida estándar. El siguiente
cuadro lista las opciones que puedan utilizarse para modificar la conducta de fmt.
Opción Efecto
-w, --width=N, -N Texto de formato para N columnas.
-p, --prefix=CADENA DE Únicamente las líneas que comienzan por CADENA DE TEXTO.
TEXTO
-u, --uniform spacing Imponga el espaciado de un espacio entre palabras, dos espacios
entre oraciones.
327
Formatear a una anchura específica
La anchura máxima del texto resultante puede especificarse con la opción -w No simplemente -N
donde -N es la anchura máxima de la línea medida en caracteres. En el siguiente ejemplo, elvis
reaplica el comando de formato al archivoside_effect.gvim, formateándolo primero a la anchura de
60 caracteres y luego a una anchura de 40 caracteres.
A menudo, se encuentra texto con algún tipo de representación o prefijo. En particular cuando se
comentan códigos fuentes o scripts, todo el texto de los comentarios necesita marcarse con el
caracter apropiado de comentario. El siguiente pedazo de texto se encuentra en el encabezado del
archivo /usr/include/db_cxx.h para el lenguaje de programación C++.
//
// As a rule, each DbFoo object has exactly one underlying DB_FOO struct
// (defined in db.h) associated with it. In some cases, we inherit directly
// from the DB_FOO structure to make this relationship explicit. Often,
// the underlying C layer allocates and deallocates these structures, so
// there is no easy way to add any data to the DbFoo class. When you see
// a comment about whether data is permitted to be added, this is what
// is going on. Of course, if we need to add data to such C++ classes
// in the future, we will arrange to have an indirect pointer to the
// DB_FOO struct (as some of the classes already have).
//
Suponga que un programador editó el comentario, añadiendo las siguientes palabras a la segunda
línea.
328
[elvis@station elvis]$ cat cxx_comment.txt
//
// As a rule, each DbFoo object has exactly one underlying DB_FOO struct
// (defined in db.h) associated with it. In some cases, but we really don't
expect many of them, we inherit directly
// from the DB_FOO structure to make this relationship explicit. Often,
// the underlying C layer allocates and deallocates these structures, so
// there is no easy way to add any data to the DbFoo class. When you see
// a comment about whether data is permitted to be added, this is what
// is going on. Of course, if we need to add data to such C++ classes
// in the future, we will arrange to have an indirect pointer to the
// DB_FOO struct (as some of the classes already have).
//
Puesto que cada línea del texto comienza por un “//” y termina en un caracter ASCII de new line, al
reajustar la línea para volver a encajar 80 caracteres, implicaría empujar algunas palabras a la
próxima línea, las cuales serían reformateadas más adelante y así sucesivamente.
Afortunadamente, el comando new line con la opción new line hace la vida más fácil.
El comando fmt hizo todo el trabajo difícil y preservó los caracteres prefijos.
El comando split
Suponga que alguien tiene un archivo demasiado grande de manejar como una sóla unidad. Por
eso, o por alguna otra razón, el comando split dividirá el archivo en archivos más pequeños, cada
uno con un número especificado de líneas o bytes.
A manera de ejemplo, elvis genera el siguiente archivo de línea sin puntos 1066.
329
[elvis@station elvis]$ fmt -70 -p"// " cxx_comment.txt
Ahora elvis utiliza el comando para dividir el archivo split en archivos más pequeños, cada uno de
200 líneas.
Aparte de cualquier opción, el comando split espera cero, o uno o dos argumentos.
Si se llama con uno o dos argumentos, el primer argumento es el nombre del archivo que se va a
dividir. Si se llama con dos argumentos, el segundo argumento se utiliza como prefijo para los
archivos recién creados. Si se llama sin argumentos o si el primer argumento es el nombre de
archivo especial “-”, el comando split operará en entrada estándar.
330
Opción Efecto
-l, --lines=N, -N Divide entrada en archivos de N líneas.
-b, --bytes=N Divide entrada en archivos de N bytes.
-l, --lines=N, -N Divide entrada en archivos de N líneas. [a]
--line-bytes=N Divide dentro de archivos máximo de Nbytes, pero realiza la división al final de
la línea.
-a, --suffix=N Utiliza sufijos de caracteres N (defecto N=2).
[a]
Al especificar N, se puede incluir un sufijo de letra, el cual actua como multiplicador:
b=512, k=1024, and M=1024*1024.
En la lección anterior, vimos que el diccionario maestro del comando aspell puede verse por medio
del siguiente comando.
El usuario elvis desearía almacenar una copia de un diccionario, pero le gustaría dividirla en
archivos de 100 líneas cada uno. Al darse cuenta que al hacerlo crearía 1.536 archivos, a sus
nombres de archivo resultantes les faltarán letras si no se aumenta la longitud del sufijo a 3(26*26
= 676). Puesto que él desea especificar la cadena de texto dict_ como un prefijo, debe proveer dos
argumentos, entonces utiliza el nombre de archivo especial “-” para hacer que split lea desde la
entrada estándar.
Ejemplos
331
Uso de fmt para limpiar correo-e
Mientras utiliza la terminal de correo masivo del comando mutt, elvis guarda y luego ve el siguiente
mensaje electrónico.
El correo-e consiste en diferentes secciones incluídas, cada una de las cuales fue escrita por un
autor diferente con un editor de texto diferente. Las primeras pocas líneas están bien, pero luego el
último comentario incluído es una línea larga.
332
[elvis@station elvis]$ fmt -p"> >> " -w60 email
> What phone numbers will everyone have in case I get lost?
> >> So it turns out that mapquest gives more sane die
> >> wreck shuns than would I were I to have to produce
> >> them from memory. So here's how to get to the house
> >> assuming you have traveled to the eastern most end
> >> of I-92. This route will take you through the heart
> >> of downtown Springfield. In my opinion it's the best
> >> way to get there because you spend the most time on
> >> the superslb that is I-92. The stretch down Market
> >> Street is narrow so drive with care. Once you turn
> >> off of Market Street take your time and gawk at
> >> the lovely historic homes cum B&Bs now operated by
> >> Wilmington's gay hospitality mafia. If you've got
> >> time to kill on the way out, Wilmington's a nice
> >> riverfront to take a stroll.
Observe que el comando fmt únicamente operó en las líneas empezadas por el prefijo “> >>” (En
este caso, había solamente una). El resto del texto fue dejado solo.
El usuario elvis ha creado una imagen abstracta mediante el programa de manipulación de imagen
gimp y ha almacenado el archivo como clouds.pnm con el formato PNM.
En la primera lección, el formato PNM fue mencionado como un simple ejemplo de imágenes de
codificación. La imagen se reduce primero a una matriz de puntos ("píxeles"), y luego el color de
333
cada píxel se codifica en tres bytes de datos crudos , el "rojo", "verde", y "azul", cada uno como un
valor de 0 a 255.
Unas pocas líneas del texto ASCII son agregadas al archivo, para identificar el formato, el número
de píxeles en cada fila, el número de filas y la "profundidad" de la imagen. (La profundidad es el
cantidad de números enteros utilizados para codificar cada componente de color. Utilizando el
esquema descrito en el párrafo anterior, la imagen tendría una profundidad de 225).
Después de experimentar un poco con el comando head, elvis decide que su archivo de imagen
conste de cuatro líneas de texto ASCII, seguidas por datos binarios.
El texto “P6” probablemente actúa como algomágico. Mágico es el término para cadenas de
texto específico (o bytes) que identifican formatos de archivo (a menudo binarios). Una
colección de identificadores "mágicos" está catalogada en el archivo /usr/share/magic. (Para
el curioso, trate grep P6 /usr/share/magic.)
Aparentemente, cualquier línea en el encabezado ASCII que comience por un “#” se interpreta
como un comentario.
Estos dos números probablemente identifican el número de píxel en una fila y el número de
filas en una imagen. Su imagen es una matriz de 256x256 píxeles.
Elvis asume que el último número define la profundidad de la imagen.
Lo restante del archivo es datos crudos. El usuario elvis desearía dividir la imagen en cuatro partes
horizontales. Por supuesto, la forma correcta de hacerlo sería utilizar un editor de imagen, tal como
gimp. En cambio, elvis va a utilizar herramientas de línea de comando.
Aunque el número de líneas y palabras reportadas por el comando no tienen sentido, el número de
caracteres es realmente el número de bytes en el archivo. Al calcular rápidamente, elvis determina
que una imagen de 256x256 píxeles, con cada píxel requiriendo 3 bytes de datos, debería ser
256*256*3=196608 bytes de longitud. El comando wc del conteo de caracteres concuerda.
334
Luego, elvis utiliza el comando split para dividir los datos crudos de la imagen en cuatro partes,
cada uno con un tamaño de 196608/4=49512 bytes.
Ahora que elvis tiene cuatro pedazos de datos crudos de la imagen original, cada uno de los cuales
contiene una cuarta parte del número de filas del original. Utilizó un editor de texto para actualizar
la información del encabezado para reflejar su cambio y almacena el encabezado actualizado en el
archivo clouds.newhdr.
Como el comando diff revela, la única modificación de elvis fue cambiar el número que define el
número de filas desde 256 hasta 256/4=64. Ahora elvis crea 4 nuevas imágenes de archivo PNM al
agregar el encabezado modificado a los datos de imagen dividida. Cuando termina, ve sus
imágenes con el visor "Eog de GNOME", eog.
335
Figure 4. Fila 3 de imagen dividida de Elvis (clouds_row3.png)
¿Por qué elvis querría utilizar herramientas de línea de comando? La primera respuesta es
precisión. La mayoría de los editores gráficos de imagen utilizan selecciones de ratón para realizar
este tipo de operaciones, las cuales llevan a la frustración cuando se tratan de realizar
modificaciones minuciosas. La segunda respuesta es la automatización. Suponga que elvis tiene
283 imágenes necesarias para realizar alguna operación. El proceso utilizado arriba pudo ser
fácilmente automatizado al grabar los comandos en un guión bash, (aunque la necesidad de
precisión o automatización es difícil de imaginar al manejar imágenes abstractas, piense en alguien
que podría estar manejando imágenes de rutina creadas por un dispositivo de imágenes médicas).
Ejercicios en línea Lab Exercise Objetivo: Uso correcto de los comandos fmt y split. Estimated
Time: 10 mins.
Especificaciones
1. Uso del comando grep para imprimir cada palabra en el archivo /usr/share/dict/words que
contiene el texto “ee”. Uso del comando fmt para reformatear la salida en líneas de 75
caracteres de anchura (por defecto). Almacene el resultado en el archivo ee_lines.txt.
2. El archivo /usr/share/doc/bash*/loadables/cut.c contiene un par de secciones grandes de
texto de comentario, cuyas líneas comiencen por el texto “ *”. Utilice el comando fmt para
reformatear sólo el texto comentario a una anchura de 40 caracteres. Almacene el
resultado en el archivo ~/cut40.c.
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
336
el restante). Los nuevos archivos existen en su directorio de inicio y todos tienen la forma
~/zone_aa, donde las letras aase repiten con cada archivo.
content_view let_
Deliverables A title Question 1
1. El archivo ee_lines.txt, que contiene cada palabra del archivo /usr/share/dict/words el cual
contiene el texto “ee”, reformateado a la anchura de 75 caracteres por línea.
2. El archivo ~/cut40.c, el cual incluye el contenido del archivo /usr/share/doc/bash-
*/loadables/cut.c, donde todas las líneas comenzadas por los caracteres “ *” han sido
reformateadas a una anchura de 40 caracteres.
337
Managing Processes
Introducción a Procesos
Conceptos clave
Discussion
Los procesos tienen que ver con el cómo se hacen las cosas
Casi cualquier cosa que suceda en un sistema Linux tiene lugar como un proceso. Si usted está
viendo este texto en un navegador, ese navegador se está ejecutando como un proceso. Si está
tecleando en una línea de comandos de la shell bash, esa shell está ejecutando como un proceso.
Si está utilizando el comando chmod para cambiar un permiso de un archivo, el comando chmod
funciona como un proceso por separado. Los procesos tienen que ver con el cómo se consigue
hacer las cosas y la responsabilidad principal del kernel de Linux es proporcionar un lugar para que
los procesos ejerzan su labor sin necesidad de tocar el campo del otro.
Los procesos son una instancia de un programa en funcionamiento. En otros sistemas operativos
los programas suelen ser grandes y elaboradas aplicaciones gráficas que se toman una gran
cantidad de tiempo para iniciar. En el mundo de Linux (y Unix), estos tipos de programas también
existen, al igual que toda una clase de programas que usualmente no tienen una contraparte en los
sistemas operativos. Estos programas están diseñados para iniciar rápidamente, especializados en
funciones y trabajan bien con otros programas. En un sistema de Linux, los procesos que ejecutan
estos programas están constantemente apareciendo y desapareciendo. Por ejemplo, considere
que el usuario maxwell escribe la siguiente línea de comandos.
¿Qué es un proceso?
338
En este momento ya estará cansado de escuchar la misma pregunta: un proceso en una instancia
de un programa en ejecución. No obstante, aquí ofrecemos una lista detallada de componentes
que constituyen un proceso.
Contexto de ejecución
Cada proceso existe (al menos hasta cierto punto) dentro de una memoria física de la
máquina. Puesto que Linux (y Unix) están diseñados para ser un entorno multiusuario, la
memoria asignada a un proceso está protegida y ningún otro proceso puede acceder a
ésta. Un proceso carga en su memoria una copia de las instrucciones ejecutables y
almacena cualquier otra información dinámica que esté manejando. Un proceso también
lleva parámetros asociados con la frecuencia de acceso que se tiene a la CPU, tales como
su estado de ejecución y su valor de niceness (pronto hablaremos más en detalle sobre
esto).
Contexto de E/S
Cada proceso interactúa hasta cierto punto con el sistema de archivos para leer y escribir
información que existe o existirá después del ciclo de vida del proceso. Los elementos de
entrada y salida (E/S) de un proceso incluyen lo siguiente:
Casi todos los procesos suelen leer información de o escribir información a fuentes
externas. En Linux, los descriptores de archivos abiertos actúan como fuentes o receptores
de información. Los procesos leen información de o escriben información a los descriptores
de archivos abiertos que pueden estar conectados a archivos regulares, nodos de
dispositivos, conexiones de red o incluso entre sí como tuberías (permitiendo la
comunicación entre procesos).
Los archivos de trazado de memoria son los archivos cuyo contenido se ha trazado
directamente en la memoria del proceso. En lugar de leer o escribir en un descriptor de
archivo, el proceso sólo accede a la dirección de memoria apropiada. Los mapas de
memoria suelen utilizarse para cargar el código ejecutable, pero también sirven para otros
tipos de acceso no secuencial a los datos.
Variables de entorno
Cada proceso mantiene su propia lista de pares nombre-valor, conocida como variables de
entorno o en general como el entorno del proceso. Los procesos por lo general heredan su
entorno en el inicio y pueden referirse a éste para obtener datos tales como el lenguaje
preferido o el editor favorito del usuario.
339
Información de herencia
Credenciales
Cada proceso también registra estadísticas para trazar la cantidad de recursos del sistema
utilizados, el número de archivos abiertos, la cantidad de tiempo de CPU, etc. La cantidad
de recursos que se le permite utilizar a un proceso también puede limitarse con un
concepto llamado límite de recursos.
Ya hemos visto varias veces el comando ps. Ahora, trataremos de familiarizarnos con una
selección más amplia de opciones asociadas a éste. Una ejecución rápida de ps --help mostrará
un resumen de más de 50 opciones diferentes para personalizar la conducta del comando ps. las
cosas se complican un poco porque diferentes versiones de Linux han desarrollado sus propias
versiones del comando ps, las cuales no utilizan las mismas convenciones para las opciones. La
versión de Linux del comando ps trata de acomodarse a diferentes versiones anteriores de Unix y
suele haber opciones múltiples para cualquier opción determinada, algunas de las cuales
comienzan con un guión inicial (“-”).
Selección de procesos
De forma predeterminada, el comando ps lista todos los procesos iniciados desde una terminal de
usuario. Aunque esta conducta es razonable, cuando los usuarios están conectados a cajas de
UNIX con terminales seriales de línea, parece un poco simplista cuando cada ventana de una
terminal dentro de un entorno gráfico X se trata como una terminal independiente. Los siguientes
modificadores de línea de comandos pueden utilizarse para expandir (o reducir) los procesos
listados por el comando ps .
340
341
Selección de salida
Como se deduce de los párrafos iniciales de esta lección hay muchos parámetros asociados con
procesos, demasiados para mostrar en una anchura estándar de terminal de 80 columnas. El
siguiente cuadro lista las opciones de línea de comando comunes que se utilizan para seleccionar
qué aspectos de un proceso se listan.
Además, las siguientes opciones pueden utilizarse para modificar la forma de presentar la
información.
El comando ps, posiblemente más que cualquier otro comando en Linux, tiene sus rarezas
asociadas con sus opciones. En la práctica, los usuarios tienden a experimentar hasta encontrar
combinaciones que les funcionen y luego se habitúan a ellas. Por ejemplo, el autor prefiere el
comando ps aux para propósitos generales de todos los procesos, mientras que otros preferirían el
comando ps -ef. El cuadro anterior ofrece una "ayuda de trabajo" bastante buena para el
principiante.
Las opciones de línea de comandos tienden a clasificarse en dos categorías, aquellas con el
tradicional guión inicial (opciones de estilo "Unix98") y otras sin (opciones de estilo "BSD"). A
menudo, una funcionalidad determinada se representa por una de cada una de ellas. Al agrupar
opciones de una sola letra, sólo pueden agruparse opciones del mismo estilo. Por ejemplo, ps axf
es lo mismo que ps a x f, pero diferente de ps a x -f.
Se espera que el comando top se ejecute desde dentro de una terminal. Éste remplazará la línea
de comandos por una tabla de los actuales procesos en ejecución, el cual se actualiza a cada
instante. A continuación se muestra la pantalla de un usuario después de ejecutar el comando top.
342
17:46:38 up 4:28, 7 users, load average: 0.07, 0.02, 0.00
101 processes: 100 sleeping, 1 running, 0 zombie, 0 stopped
CPU states: 3.4% user 1.0% system 0.0% nice 0.0% iowait 95.4% idle
Mem: 255232k av, 232796k used, 22436k free, 0k shrd, 32404k buff
146208k actv, 33884k in_d, 4716k in_c
Swap: 522104k av, 88368k used, 433736k free 104280k cached
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND
1150 einstein 15 0 4468 4108 2252 S 2.9 1.6 0:51 0 metacity
1186 einstein 15 0 3132 2112 1436 S 0.9 0.8 0:04 0 battstat-appl
3057 einstein 15 0 19596 18M 12356 S 0.9 7.5 0:06 0 galeon-bin
3622 maxwell 22 0 1088 1088 856 R 0.9 0.4 0:00 0 top
1 root 15 0 108 76 52 S 0.0 0.0 0:04 0 init
2 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 keventd
3 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kapmd
4 root 34 19 0 0 0 SWN 0.0 0.0 0:00 0 ksoftirqd_CPU
9 root 25 0 0 0 0 SW 0.0 0.0 0:00 0 bdflush
5 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kswapd
6 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kscand/DMA
7 root 15 0 0 0 0 SW 0.0 0.0 0:06 0 kscand/Normal
8 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kscand/HighMe
10 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kupdated
11 root 25 0 0 0 0 SW 0.0 0.0 0:00 0 mdrecoveryd
15 root 15 0 0 0 0 SW 0.0 0.0 0:01 0 kjournald
Mientras el comando está ejecutándose, el teclado está "vivo". En otras palabras, el comando top
responderá a pulsaciones sin esperar a la tecla enter. El siguiente cuadro lista algunas de las
teclas más utilizadas.
Los últimos dos comandos, los cuales pueden matar o renice un proceso utilizan conceptos que
cubriremos con más detalle en una próxima lección.
Aunque por lo general top funciona sin la configuración de línea de comandos es compatible con
las siguientes opciones:
Opción Efecto
-d Demora segundos segundos entre actualizaciones (por defecto = 5 segundos).
343
segundos
-q Actualiza tan pronto como sea posible.
-n N Se ejecuta para iteraciones N, luego sale.
-b Se ejecuta en "modo por lote" simplemente como si escribiera a una terminal tonta.
Al igual que el comando top, la aplicación Monitor del sistema presenta una lista de procesos
ejecutándose en la máquina local, actualizando la lista cada pocos segundos. En su configuración
por defecto, la aplicación Monitor del sistema provee una interfaz mucho más simple: lista sólo los
procesos pertenecientes al usuario que inició la aplicación y reduce el número de columnas a la
memoria del comando del proceso, el propietario, ID de proceso, las medidas simples de la
memoria del proceso y la utilización de la CPU. Los procesos pueden clasificarse por cualquiera de
estos campos con un sólo clic en el título de la columna.
Cuando se hace click derecho en un proceso, un menú emergente permite al usuario realizar
muchas de las acciones que top le permitió, tales como reniciar o matar un proceso a través de una
interfaz más sencilla (y no tan flexible).
Por último, el Monitor de Sistema provee un segundo panel, el cual muestra gráficas de todo el uso
de la CPU y de la memoria versus tiempo y un cuadro de uso del disco (esencialmente la salida del
comando df).
A menudo, los usuarios tratan de localizar información acerca de procesos identificados por el
comando que están ejecutando o el usuario que está ejecutándolos. Una técnica es listar todos los
procesos y utilizar el comando grep para reducir la información. A continuación, maxwell primero
busca todas las instancias del demonio sshd y luego busca los procesos pertenecientes al usuario
maxwell.
344
[maxwell@station maxwell]$ ps aux | grep sshd
root 829 0.0 0.0 3436 4 ? S 09:13 0:00 /usr/sbin/sshd
maxwell 2200 0.0 0.2 3572 640 pts/8 S 10:10 0:00 grep sshd
[maxwell@station maxwell]$ ps aux | grep maxwell
root 2109 0.0 0.3 4108 876 pts/8 S 10:05 0:00 su - maxwell
maxwell 2112 0.0 0.4 4312 1268 pts/8 S 10:05 0:00 -bash
maxwell 2146 1.4 8.3 89256 21232 pts/8 S 10:05 0:04 /usr/lib/mozilla-
maxwell 2201 0.0 0.2 2676 724 pts/8 R 10:10 0:00 ps aux
maxwell 2202 0.0 0.2 3576 644 pts/8 S 10:10 0:00 grep maxwell
Aunque maxwell puede encontrar la información que necesita hay algunos aspectos no muy
agradables.
El comando pgrep fue creado para tratar estos problemas. pgrep permite a los usuarios listar
rápidamente procesos por nombre de comando, usuario, terminal o grupo.
Table 1. Opciones comunes para especificar el criterio de selección del proceso pgrep.
Opción Efecto
-n Selecciona únicamente los procesos coincidentes iniciados más recientemente.
-u Selecciona procesos pertenecientes al usuario USER.
USER
-t TERM Selecciona procesos controlados por terminal TERM.
Además, la siguiente opción puede utilizarse para modificar el formato de la salida del comando.
Opción Efecto
-d Usa delimitador para delimitar cada ID de proceso (por defecto se utiliza una
delimitador nueva línea).
-l Lista el nombre del proceso y el ID del proceso.
A manera de ejemplo, maxwell repetirá dos listados del proceso anterior mediante el comando
pgrep. [1]
345
[maxwell@station maxwell]$ pgrep -l sshd
829 sshd
[maxwell@station maxwell]$ pgrep -lu maxwell
2112 bash
2146 mozilla-bin
2155 mozilla-bin
2156 mozilla-bin
2157 mozilla-bin
Ejemplos
En la siguiente transcripción, maxwell utiliza el comando ps -e u para listar todos los procesos (-e)
con el formato de "usuario orientado" (u).
[maxwell@station maxwell]$ ps -e u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1380 76 ? S Oct12 0:04 init [
root 2 0.0 0.0 0 0 ? SW Oct12 0:00 [keventd]
root 3 0.0 0.0 0 0 ? SW Oct12 0:00 [kapmd]
...
root 174 0.0 0.0 0 0 ? SW Oct12 0:00 [kjournald]
root 250 0.0 0.0 1356 4 tty2 S Oct12 0:00 /sbin/mingetty tt
root 496 0.0 0.1 2104 448 ? S Oct12 0:00 /sbin/dhclient -1
root 566 0.0 0.0 1448 160 ? S Oct12 0:00 syslogd -m 0
root 570 0.0 0.0 1376 164 ? S Oct12 0:00 klogd -x
rpc 588 0.0 0.0 1548 104 ? S Oct12 0:00 portmap
...
maxwell 4202 0.0 1.3 57948 3400 ? S Oct12 0:02 nautilus --no-def
maxwell 4204 0.0 0.1 16392 436 ? S Oct12 0:00 magicdev --sm-cli
maxwell 4207 0.0 0.5 16784 1500 ? S Oct12 0:00 eggcups --sm-clie
maxwell 4210 0.0 0.3 11596 988 ? S Oct12 0:00 pam-panel-icon --
maxwell 4212 0.1 0.8 24464 2152 ? S Oct12 0:41 /usr/bin/python /
root 4213 0.0 0.0 1416 136 ? S Oct12 0:00 /sbin/pam_timesta
maxwell 4220 0.0 0.3 17024 1012 ? S Oct12 0:00 /usr/libexec/noti
maxwell 4293 2.4 1.4 18356 3760 ? S Oct12 15:28 gnome-system-moni
apache 5048 0.0 0.6 18424 1776 ? S Oct12 0:00 /usr/sbin/httpd
...
maxwell 13166 0.7 0.5 4304 1392 pts/5 S 07:35 0:00 -bash
maxwell 13200 0.0 0.2 2696 744 pts/5 R 07:35 0:00 ps -e u
346
En la siguiente transcripción, maxwell utiliza el comando ps -U maxwell l para listar todos sus
procesos (-U maxwell) con el formato "largo " (l).
En la siguiente transcripción, maxwell utiliza el comando ps -C bash j para listar todas las
instancias del comando bash (-C bash) con el formato de "trabajo orientado" (j).
El formato de trabajo orientado se enfoca en los procesos padre, grupos de proceso, grupos de
sesión y terminales de control. Muchos de estos conceptos se discutirán más tarde en otros
cuadernos.
Intrigado porque el proceso padre de muchas de estas shells parece ser el proceso ID 1184,
maxwell continúa examinando ese proceso individual.
347
[maxwell@station maxwell]$ ps u 1184
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
einstein 1184 0.2 3.3 26900 8660 ? S Oct12 2:51 /usr/bin/
gnome-te
Aparentemente, todas las shells bash se iniciaron desde dentro de una gnome-terminal.
Intrigado por ver los aspectos que un proceso puede visualizar con el comando ps, maxwell utiliza
ps L para listar los posibles encabezados.
[maxwell@station maxwell]$ ps L
%cpu %CPU
%mem %MEM
alarm ALARM
args COMMAND
blocked BLOCKED
bsdstart START
bsdtime TIME
c C
...
vsize VSZ
vsz VSZ
wchan WCHAN
Intrigado por el campo alarm, maxwell desea ver los procesos que tienen alarmas pendientes.
Utiliza la opción -o para listar todas las alarmas pendientes y comandos.
348
Estas son las utilidades que piden ser notificadas cada 15 minutos, cada hora, etc.,
presumiblemente para sondear alguna actividad.
Ejercicios en línea Lab Exercise Objetivo: Ver la información sobre los procesos Tiempo
estimado: 20 minutos.
Especificaciones
Con el fin de tener un conjunto fijo de procesos para examinar, usted debe tomar una instantánea
de todos los procesos actuales en su máquina. Utilice la siguiente secuencia de comandos para
capturar primero los encabezados de las columnas del comando ps aux dentro de un archivo
llamado snapshot. Luego vuelva a ejecutar el comando ps aux, eliminando el encabezado y
clasificando el resto de la salida de acuerdo al tamaño de la memoria virtual de cada proceso. La
lista clasificada de procesos se agregará luego al encabezado previamente capturado en el archivo
snapshot.
1. El archivo ~/biggest.pid que contiene el ID de proceso del proceso con la memoria virtual
más grande.
2. El archivo ~/pstates.txt que contiene la columna extraída de los estados de proceso, a
excepción de la línea de encabezado.
3. El archivo ~/nmingetty.txt que contiene el número de instancias del programa
/sbin/mingetty ejecutándose en su máquina.
349
4. El archivo ~/nroot.txt que contiene el número de procesos ejecutándose como el usuario
root de la máquina.
350
Estados del proceso
Conceptos clave
• En Linux, el primer proceso, /sbin/init, lo inicia el kernel en el arranque. Todos los demás
procesos son el resultado de un proceso padre que se duplica o bifurca.
• Un proceso comienza a ejecutar un nuevo comando a través de un proceso llamado
execing.
• Los nuevos comandos suelen ejecutarse mediante un proceso (a menudo una shell)
primero mediante una bifurcación y luego ejecutando un nuevo comando. Este mecanismo
se conoce como el mecanismo fork y exec.
• Los procesos siempre pueden encontrarse en uno de los cinco estados: ejecutable,
dormido voluntario, dormido involuntario, detenido o zombi.
• La ascendencia del proceso puede verse con el comando pstree.
• Cuando un proceso muere, el padre del proceso debe recolectar su información del código
de retorno y del uso de recursos.
• Cuando un padre muere antes que sus hijos, el primer proceso hereda los huérfanos
(usualmente /sbin/init).
Discussion
Los nuevos procesos se crean mediante una técnica llamada forking. Cuando un proceso
se bifurca, crea un duplicado de sí mismo. Inmediatamente después de una bifurcación, el
proceso recién creado (el hijo) es un duplicado exacto del proceso original (el padre). El
hijo hereda una copia idéntica de la memoria del proceso original, los archivos abiertos de
padre, copias idénticas de los parámetros del padre, tales como el directorio de trabajo
actual o umask. La única diferencia entre el padre y el hijo es la información heredada del
hijo (el hijo tiene un ID de proceso diferente y un proceso de padre diferente, para los
principiantes), y (para los programadores en la audiencia) el valor de retorno de la llamada
al sistema fork().
351
int rc, child_pid;
rc = fork();
if (rc == -1) { perror("bad fork"); }
else if (rc == 0) { do_child(); }
else {
child_pid = rc;
do_parent(child_pid);
}
Cuando un proceso desea crear un nuevo proceso, acude al sistema de llamado fork() (sin
argumentos). Aunque sólo un proceso entra en el llamado fork(), dos procesos retornan.
Para el proceso recién creado (el hijo), el valor de retorno es 0. Para el proceso original (el
padre), el valor de retorno es el ID del proceso de hijo. Al bifurcar este valor, el hijo puede
ahora salir a hacer cualquier cosa que hubiera empezado a hacer (que suele involucrar
exec(), ver lo siguiente) y el padre puede continuar haciendo sus cosas.
Algunos de los programas pueden utilizar fork sin ejecutar un nuevo comando. Ejemplos
incluyen demonios de red, que bifurcan un nuevo hijo para manejar una conexión de un
cliente específico, mientras el padre retorna para escuchar nuevos clientes. Otros
programas podrían utilizar exec sin bifurcación. Ejemplos incluyen al comando login, el
352
cual se convierte en la shell de inicio de sesión del usuario después de confirmar la
contraseña del usuario. Sin embargo, para las shells en particular, fork y exec suelen ir de
la mano. Cuando se ejecuta un comando, la shell bash primero bifurca una nueva shell
bash. Luego, el hijo ejecuta el nuevo comando apropiado, mientras que el padre espera
que el hijo muera para generar un nuevo intérprete de comandos.
Tras el arranque del sistema, una de las responsabilidades del sistema del Kernel de Linux es
iniciar el proceso por primera vez (usualmente/sbin/init). Todos los otros procesos son iniciados
porque se bifurcó un proceso ya existente.[1]
Debido a que cada proceso a excepción del primero se crea por bifurcación, dentro de los procesos
existe un linaje bien definido de relaciones padre e hijo. El primer proceso iniciado por el kernel
inicia fuera del árbol de familia, el cual puede examinarse con el comando pstree.
353
Cómo muere un proceso
Cuando un proceso muere ya sea que muera normalmente seleccionando exit o anormalmente
como el resultado de recibir una señal. Aquí tratamos la salida normal del proceso, dejando para
más adelante la discusión acerca sobre la señales.
Hemos mencionado anteriormente que los procesos dejan atrás un código de estatus cuando
mueren (también llamado valor de retorno) en la forma de un número entero, (recuerde la shell
bash que utiliza la variable $? para almacenar el valor de retorno del comando ejecutado
previamente). Cuando un proceso sale, todos sus recursos se liberan, a excepción del código de
retorno (y alguna información de utilización de recursos contables). Es responsabilidad del padre
del proceso coleccionar esta información y liberar los últimos recursos del hijo muerto. Por ejemplo,
cuando la shell se bifurca y exec el comando chmod, es responsabilidad de la shell bash padre
recoger el valor de retorno del comando cerrado chmod.
Huérfanos
Si es responsabilidad de los padres limpiar después de sus hijos, ¿qué sucede si el padre muere
antes que el hijo? El hijo queda huérfano. Una de las responsabilidades especiales del primer
proceso iniciado por el kernel es "adoptar" huérfanos, (observe que en la salida del comando
pstree, el primer proceso tiene un número desproporcionado de hijos. La mayoría de estos fueron
adoptados como huérfanos de otros procesos).
Zombis
Entre el momento en que un proceso sale, liberando la mayoría de sus recursos, y el momento en
que su padre recoge su valor de retorno, liberando el resto de sus recursos, el proceso hijo se
encuentra en un estado especial conocido como Zombi. Cada proceso pasa a través de un estado
transitorio zombi. Los usuarios tienen que estar mirando justo en el momento preciso (con el
comando ps, por ejemplo) para ver un zombi. Ellos se aparecen en la lista de procesos, pero no
ocupan memoria, ni tiempo de CPU, ni ningún otro sistema de recursos. Ellos son sólo la sombra
de un proceso anterior esperando que su padre llegue y los termine.
Ocasionalmente, los procesos padres pueden ser descuidados. Comienzan procesos hijos pero
nunca regresan a limpiar lo que dejan. Cuando esto ocurre (usualmente debido a un error de
programador), el hijo puede salir, entrar en estado zombi y quedarse ahí. Esto suele suceder
cuando los usuarios son testigos de procesos zombis mediante el comando ps, por ejemplo.
Deshacerse de zombis es quizás el concepto básico más incomprendido de Linux (y Unix). Mucha
gente dirá que no hay forma de deshacerse de ellos, excepto volviendo a arrancar la máquina.
¿Sabe cómo deshacerse de zombis de larga vida utilizando las claves tratadas en esta sección?
La sección anterior trató la manera como se inician y mueren los procesos. Mientras los procesos
están vivos, siempre están en uno de los cinco estados del proceso, los cuales efectúan el cómo y
cuándo tienen acceso a la CPU. El siguiente listado muestra los cinco estados, junto con la letra
convencional utilizada por ps, top y otros comandos para identificar el estado actual de un
proceso.
354
Ejecutable (R)
Como el nombre lo implica, un proceso que está dormido voluntario ha elegido estar así.
Por lo general, este es un proceso que no tiene nada que hacer hasta que suceda algo
interesante. Un ejemplo clásico es el demonio de red httpd, el cual es un proceso que
implementa un servidor de red. En medio de solicitudes de un cliente (navegador de red),
el servidor no tiene nada que hacer, y elige irse a dormir. Otro ejemplo sería el comando
top, que lista procesos cada cinco segundos. Mientras espera que pasen los cinco
segundos, se duerme voluntariamente. Cuando el proceso esté interesado en que algo
suceda (tal como cuando el cliente de red hace una solicitud o los cinco segundos expiran),
el proceso dormido vuelve al estado ejecutable.
Como lo mencionamos antes, cada proceso muriendo pasa a través de un estado zombi
transitorio. No obstante, en ocasiones, algunos se quedan en ese estado. Los procesos
zombis han terminado de ejecutar, han liberado toda su memoria y casi todos sus
recursos. Dado que no están consumiendo recursos, son poco más que una molestia que
puede aparecer en listados de procesos.
355
Ver estados de procesos
Cuando se ve la salida de comandos tales como ps y top, los estados de procesos suelen
enumerase bajo el encabezado STAT. El proceso es identificado por una de las siguientes letras:
• Ejecutable - R
• Dormido - S
• Detenido - T
• Dormido ininterrumpible - D
• Zombi - Z
Ejemplos
Un proceso dormido (voluntario). El proceso init está esperando que algo "interesante" suceda
tal como un huérfano recién creado a heredar.
Un proceso dormido(involuntario) o "bloqueado". El comando updatedb está compitiendo por
algún recurso en el sistema probablemente con la otra instancia del proceso updatedb justo
debajo de éste.
Un proceso detenido. Este editor vim probablemente ha sido suspendido manualmente con la
secuencia de teclas CONTROL-Z.
Un proceso zombi probablemente abandonado por un navegador de red galeon negligente.
Un proceso ejecutable en este caso el comando ejecutable ps.
Ejercicios en línea
Especificaciones
1. Con el fin de explorar los estados de procesos debemos crear procesos que estén
compitiendo por los mismos recursos. Utilice un editor de texto sencillo para crear el
siguiente guión, almacénelo como ~/clobber_it.sh y hágalo ejecutable.
356
[maxwell@station maxwell]$ cat clobber_it.sh
#!/bin/bash
2. Aunque este guión escribirá al pobre archivo sobrecargado 1000 veces, lo hará de forma
secuencial y así nunca estará compitiendo por acceder al archivo. Dado que necesitamos
procesos múltiples compitiendo por el mismo recurso, cree también el mismo script.
Nómbrelo ~/clobber_it_lots.sh y hágalo ejecutable.
Deliverables A title
357
Programación de procesos: nice y renice
Conceptos clave
Discussion
Una de las tareas fundamentales del kernel de Linux es asegurar que los procesos compartan
recursos del sistema de manera efectiva. Uno de los recursos más importantes que tiene que
compartirse es la CPU. La forma en que el kernel decide qué proceso tiene que ejecutarse en la
CPU y la hora se conoce como programación.
Cada proceso tiene dos valores que influyen en su programación. El primero es un valor dinámico
que el kernel cambia constantemente. El segundo, es un valor fijo que sólo de vez en cuando el
usuario lo cambia. En la comunidad de código abierto, la nomenclatura utilizada para describir
estos dos valores ha sido inconsistente lo que lleva a la confusión. En lo posible, este texto tratará
de ser consistente con los comandos ps y top y se referirá al primer valor (dinámico) como la
prioridad del proceso y al segundo valor (fijo) como el niceness del proceso.
Recientemente, se ha prestado mucha atención a los métodos utilizados por el kernel de Linux
para implementar programación y la técnica ha variado con cada lanzamiento del kernel. Aunque la
siguiente discusión no es correcta en detalle comunica en esencia la forma como el kernel de Linux
programa procesos.
Para ilustrar la programación de un modo más fácil, maxwell iniciará cuatro versiones del comando
cat, ejecutándose en el segundo plano, (los procesos se pueden ejecutar en segundo plano
agregando el signo “&”), como se discutirá en una lección más adelante. Los comandos cat leen
desde /dev/zero (un seudo dispositivo que actúa como una fuente infinita de ceros binarios) y
escriben en /dev/null (un seudo dispositivo que bota todo lo que se escribe en él).
¿Por cuánto tiempo se ejecutarán estos comandos cat? Para siempre. El usuario maxwell controla
los procesos en su máquina mediante el comando top.
358
00:25:43 up 11:07, 10 users, load average: 6.02, 5.08, 3.01
128 processes: 121 sleeping, 7 running, 0 zombie, 0 stopped
CPU states: 8.5% user 3.2% system 4.6% nice 0.0% iowait 83.5% idle
Mem: 255232k av, 251560k used, 3672k free, 0k shrd, 36592k buff
162724k actv, 33644k in_d, 3952k in_c
Swap: 522104k av, 145148k used, 376956k free 74780k cached
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND
6698 maxwell 25 0 404 400 352 R 19.3 0.1 0:24 0 cat
6699 maxwell 22 0 400 400 352 R 19.3 0.1 0:24 0 cat
6700 maxwell 24 0 400 372 352 R 19.3 0.1 0:24 0 cat
6757 einstein 21 0 25992 24M 3596 R 17.4 9.7 0:04 0 jade
6701 maxwell 25 0 400 400 352 R 16.4 0.1 0:24 0 cat
6686 maxwell 35 10 6608 4836 1108 R N 4.8 1.8 0:44 0 xlyap
6758 maxwell 19 0 1120 1120 852 R 2.9 0.4 0:00 0 top
1063 root 15 0 33304 16M 692 S 1.9 6.5 33:56 0 X
1 root 15 0 108 76 52 S 0.0 0.0 0:04 0 init
2 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 keventd
...
Mientras observa el comando top, maxwell observa que los valores en la tercera columna (con la
etiqueta PRI) están en constante cambio. Estos son los valores de "prioridad" dinámicos del
proceso mencionados anteriormente. La cuarta columna (con la etiqueta NI) es el valor fijo de
"niceness" del proceso.
Cuando se programan los procesos, el kernel da a cada proceso un puñado de contadores. Cada
vez que un proceso se programa en la CPU, entrega uno de sus contadores. Cuando decide qué
proceso programar en la próxima CPU, el kernel escoge un proceso ejecutable con la mayoría de
contadores. Eventualmente, el kernel alcanzará un estado donde todos los procesos ejecutables
han utilizado sus contadores. Esto se conoce como el final de una programación epoch y en este
punto el kernel inicia todos los procesos otra vez con un puñado de contadores.
Observe que los procesos que no están en estado ejecutable nunca entregan sus contadores. Sin
embargo, si un proceso dormido se despertara de repente (porque algo interesante ha sucedido) y
fuera enviado al estado ejecutable, muy probablemente tendría más contadores que procesos
ejecutándose por un tiempo y le gustaría que fueran programados rápidamente en la CPU.
¿Cómo se relaciona esto con los valores demostrados en la columna PRI? Piense en esta columna
como si fuera un número de procesos de contadores, restados de 40. Por lo tanto, los procesos
con una prioridad inferior (como es listado por el comando top) tienen una ventaja en la
programación. En la salida de arriba, los comandos cat, en constante ejecución, están
consumiendo sus contadores. Sin embargo, el proceso init que está durmiendo en el segundo
plano, no lo está.
Proceso niceness
Como se mencionó anteriormente, cada proceso también tiene un valor estático conocido como su
valor de niceness. Este valor tiene un rango que va de -20 a 19 para cualquier proceso, iniciando
en 0 por defecto. ¿Cómo influye un niceness de un proceso en su programación? Al comienzo de
la programación puede pensar que el kernel resta un valor de niceness del proceso del número de
contadores del proceso que se le ha asignado. Como resultado de procesos más, "amables"
359
(aquellos con un alto valor de niceness) obtienen menos contadores y por lo tanto menos tiempo
en la CPU, mientras que procesos más "ambiciosos" (aquellos con un valor de niceness menor que
0) obtienen más contadores y más tiempo en la CPU. Si un proceso "amable" es el único
ejecutándose en la máquina entonces obtendría acceso total a la CPU.
Suponga que maxwell fuera a ejecutar una simulación física que le tomaría varios días completar.
Al incrementar el valor de niceness del proceso, el proceso pacientemente esperaría si alguien más
estuviera ejecutando procesos en la máquina. Si nadie más estuviera en la máquina, la simulación
física tendría acceso total a la CPU.
Hay varias técnicas por las cuales maxwell podría alterar su valor de niceness del proceso.
Uso del comando nice para iniciar un comando con prioridad baja
El comando nice se utiliza para establecer un valor de niceness del proceso al iniciar el proceso.
Cuando maxwell inicia su simulación (la cual es un ejecutable en su directorio de inicio llamado
~/simulation) lo hace lo más nice posible, con el valor de +19, (también coloca el proceso en
segundo plano. No se preocupe por esto en este momento puesto que lo abarcaremos en una
próxima lección).
Observe que la sintaxis puede confundir. El símbolo -19 no debería considerarse negativo 19 sino
en cambio la opción numérica 19. El usuario maxwell de nuevo controla los procesos mediante el
comando top. Los primeros pocos procesos listados se enumeran a continuación.
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND
7192 maxwell 25 0 400 400 352 R 22.7 0.1 0:35 0 cat
7193 maxwell 25 0 400 400 352 R 22.7 0.1 0:35 0 cat
7191 maxwell 25 0 400 400 352 R 21.9 0.1 0:36 0 cat
7194 maxwell 25 0 404 404 352 R 21.9 0.1 0:35 0 cat
1184 einstein 15 0 11140 8708 3144 R 4.7 3.4 1:28 0 gnome-termina
7198 maxwell 39 19 404 404 352 R N 2.1 0.1 0:02 0 simulation
4293 maxwell 15 0 5164 5016 2384 S 1.7 1.9 6:07 0 gnome-system-
Como algo conveniente, el comando ps representa el estado de proceso con una “N” para
indicar que el proceso ha aumentado su valor de niceness.
Dado que otros comandos cat están utilizando la máquina, la simulación de maxwell sólo está
usando cerca del 2.1 % de la CPU.
Luego, maxwell se deshace de los comandos cat (mediante las técnicas que veremos en la
siguiente lección).
360
[maxwell@station maxwell]$ killall cat
[maxwell@station maxwell]$
[3] Terminated cat /dev/zero >/dev/null
[4] Terminated cat /dev/zero >/dev/null
[5] Terminated cat /dev/zero >/dev/null
[6] Terminated cat /dev/zero >/dev/null
Cuando observa el comando top una vez más, su simulación, ahora el (casi) único proceso en la
máquina, está recibiendo todo el tiempo de la CPU.
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND
7198 maxwell 39 19 404 404 352 R N 94.4 0.1 0:51 0
simulation
7210 maxwell 20 0 1120 1120 852 R 2.8 0.4 0:00 0 top
1063 root 15 0 33516 17M 832 S 1.9 7.0 47:01 0 X
4212 maxwell 15 0 5828 3012 1072 S 0.9 1.1 0:21 0 rhn-
applet-gu
1 root 15 0 108 76 52 S 0.0 0.0 0:04 0 init
Como una sutileza adicional, el número especificado es el número que va a agregarse al valor de
niceness de la shell actual. Esto rara vez se nota, dado que la mayoría de las shells se ejecutan
con un niceness de 0. No obstante, si una shell estuviera ejecutándose con un valor de niceness
de 10, la siguiente opción de línea de comando resultaría en la simulación que está ejecutándose
con un valor de niceness de 15.
El comando renice puede utilizarse para cambiar el niceness de un proceso en ejecución. Los
procesos pueden ser especificados por el ID del proceso, nombre de usuario, o nombre de grupo,
dependiendo de cuál de las siguientes opciones se utilicen.
Opción Efecto
-p interpreta los argumentos restantes como ID del proceso (por defecto)
-u interpreta los argumentos restantes como nombres de usuarios.
-g interpreta los argumentos restantes como ID de grupo.
361
El proceso está recibiendo una gran cantidad de tiempo de la CPU.
El proceso tiene por defecto un valor de niceness de 0.
Decide ser más cortés con otras personas que podrían estar utilizando la máquina y utiliza el
comando renice para elevar el valor de niceness del proceso. En la ausencia de cualquier opción,
el comando renice espera un valor de niceness y un ID de proceso como sus dos argumentos.
Uso del comando top para otorgar otro valor de nice a un proceso
Como se mencionó antes, el comando top utiliza la tecla r para cambiar el valor nice de un
proceso. Mientras controla procesos con top, al presionar r abrirá el siguiente diálogo que aparece
encima de la lista de procesos.
¿Qué sucedería si maxwell fuera malintencionado y quisiera hacer su simulación mucho más
ambiciosa en lugar de más amable? Afortunadamente, para otros usuarios en la máquina, los
usuarios normales no pueden bajar el niceness de un proceso. Esto trae dos implicaciones.
1. Debido a que los procesos inician con un niceness de 0 por defecto, los usuarios normales
no pueden hacer procesos "ambiciosos" con valores de niceness negativos.
2. Una vez un proceso ha sido hecho nice, los usuarios normales no pueden volverlo "normal"
otra vez .
Suponga que el administrador observó que la simulación de maxwell estaba tomando mucho
tiempo de la CPU. Ella pudo utilizar el comando renice como root para elevar el niceness de
maxwell y maxwell no pudo restaurarlo.
Ejemplos
Ver prioridades
Abajo hay varias tomas de pantalla ps -alx a medida que se ejecuta el proceso. Observe los
campos "PRI" y "nice" a lo largo del tiempo. Son los campos 5 y 6 de izquierda a derecha.
362
[maxwell@station maxwell]$ find / 2>/dev/null >/dev/null &
[1] 2739
[maxwell@station maxwell]$ ps -alx
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
...
000 501 2676 898 15 0 4232 1544 wait4 S pts/0 0:00 bash
000 501 2739 2676 18 0 3284 644 - R pts/0 0:00 find /
000 501 2740 2611 16 0 3804 948 wait4 S pts/1 0:00 /bin/bash -
040 501 2741 2740 16 0 3808 1004 wait4 S pts/1 0:00 /bin/bash -
000 501 2742 2741 17 0 3144 1232 - R pts/1 0:00 ps -alx
000 501 2743 2741 17 0 3144 420 pipe_w S pts/1 0:00 tail
...
Luego, maxwell utiliza el comando renice para alterar el valor de niceness del proceso.
Debido a que el valor de niceness se ha incrementado, el proceso tiene valores más altos de
prioridad (implicando menos acceso a la CPU por una época de programación).
El nuevo valor de niceness.
Dado que a los usuarios estándar no se les permiten valores de niceness más bajos, el comando
falla.
363
Cambio de prioridades con renice
Al utilizar la opción -u, el usuario maxwell puede cambiar los valores de niceness para todos los
procesos al mismo tiempo.
364
Ejercicios en línea Lab Exercise Objetivo: Cambiar las prioridades de los procesos.Estimated
Time: 10 mins.
Especificaciones
1. En otra terminal, utilice el comando renice para cambiar el valor de niceness de todos los
procesos que le pertenezcan hasta 5 (podría considerar el utilizar el comando pgrep junto
con el comando xargs para este paso).
2. Después de completar el último paso, cambie el valor de niceness del proceso cat (iniciado
en el paso 1) a 10.
3. Utilice el comando nice para iniciar otro comando cat (de nuevo leyendo /dev/zero
redirigido a /dev/null) con el valor de niceness de 15.
Califique su ejercicio con ambas instancias del comando cat aún ejecutándose.
Limpieza
Cuando haya terminado de calificar su ejercicio puede detener todos sus procesos cat con la
secuencia de control CTRL-C.
365
Envío de señales
Conceptos clave
• Las señales son una forma de bajo nivel de la comunicación entre procesos que surgen de
una variedad de recursos, incluyendo el kernel, la terminal y otros procesos.
• Las señales se distinguen por los números de señales que tienen nombres y usos
simbólicos. Los nombres simbólicos para los nombres de señales pueden listarse con el
comando kill -l.
• El comando kill envía señales a otros procesos.
• Tras recibir una señal, un proceso puede ya sea, ignorarla, reaccionar de un modo
especificado por defecto de kernel o implementar un manejador de señal personalizado.
• Convencionalmente, el número de señal 15 (SIGTERM) se utiliza para solicitar la
terminación de un proceso.
• La señal número 9 (SIGKILL) termina un proceso y no puede anularse.
• Los comandos pkill y killall pueden utilizarse para enviar señales a procesos
especificados por nombre de comando o el usuario a quienes pertenecen.
• Otras utilidades, tales como top y el Monitor de sistema GNOME, también pueden
utilizarse para enviar señales.
Discussion
Señales
Linux (y Unix) utiliza señales para notificar procesos de eventos anormales, y como un mecanismo
primitivo de comunicación entre procesos. Algunas veces, las señales se conocen como
interrupciones de software, porque pueden interrumpir el flujo normal de ejecución de un proceso.
El kernel utiliza señales para notificar procesos de conducta anormal, como si el proceso tratase de
dividir un número por cero o tratase de acceder memoria que no le perteneciera.
Los procesos también pueden enviar señales a otros procesos. Por ejemplo, una shell bash podría
enviar una señal a un proceso xclock. El proceso receptor sabe muy poco acerca de los orígenes
de la señal. No sabe si la señal se originó del kernel o de algún otro proceso, todo lo que sabe es
que recibió una señal.
Sin embargo, hay diferentes sabores de señales. Los diferentes sabores tienen números
simbólicos pero también se identifican con números enteros. Los varios números enteros y el
nombre simbólico que les son asignados pueden listarse por medio del comando kill -l o los puede
encontrar en la página del manual signal(7).
366
[einstein@station einstein]$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 33) SIGRTMIN 34) SIGRTMIN+1
35) SIGRTMIN+2 36) SIGRTMIN+3 37) SIGRTMIN+4 38) SIGRTMIN+5
39) SIGRTMIN+6 40) SIGRTMIN+7 41) SIGRTMIN+8 42) SIGRTMIN+9
43) SIGRTMIN+10 44) SIGRTMIN+11 45) SIGRTMIN+12 46) SIGRTMIN+13
47) SIGRTMIN+14 48) SIGRTMIN+15 49) SIGRTMAX-15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1
Linux, al igual que varias versiones de Unix, implementa 32 señales "normales". En Linux, las
señales se numeran a partir de 32 hasta 63 (que no son estándar entre las varias versiones de
Unix) y son señales en "tiempo real" y van más alla del objetivo de este texto.
Hay una variedad de razones por las cuales las señales se pueden enviar a un proceso como se
ilustra con los siguientes ejemplos.
Excepciones de hardware
El proceso le pidió al hardware realizar alguna operación errónea. Por ejemplo, el kernel
enviará un proceso SIGFPE (señal número 8) si realiza una división por 0.
Los procesos pueden necesitar ser notificados de alguna condición anormal del software.
Por ejemplo, cada vez que muere un proceso, el kernel envía un SIGCHLD (número de
señal 17) al padre del proceso. Otro ejemplo, las aplicaciones gráficas X reciben un
SIGCHLD (número de señal 17) cada vez que su ventana cambia de tamaño, para poder
responder a la nueva geometría.
Interrupciones de terminal
Otros procesos
Los procesos pueden elegir enviar señales a cualquier otro proceso perteneciente al
mismo usuario. El comando kill está diseñado para hacer justo esto.
367
El comando kill se utiliza para enviar señales a otros procesos. Éste espera ser llamado con una
opción numérica o simbólica que especifica la señal a enviar y un ID de proceso que especifica el
proceso que debería recibirlo. A manera de ejemplo, las siguientes líneas de comando envían un
SIGCHLD (número de señal 17) al proceso xclock, el ID del proceso número 8060.
[einstein@station einstein]$ ps
PID TTY TIME CMD
7985 pts/5 00:00:00 bash
8060 pts/5 00:00:01 xclock
8061 pts/5 00:00:00 ps
[einstein@station einstein]$ kill -17 8060
[einstein@station einstein]$ kill -CHLD 8060
[einstein@station einstein]$ kill -SIGCHLD 8060
Cuando se utiliza el nombre simbólico para especificar una señal, el prefijo “SIG” (compartido por
todas las señales) puede ser incluído u omitido.
Recepción de señales
Cuando un proceso recibe una señal puede realizar una de las siguientes tres acciones.
Para cada tipo de señal hay una respuesta predeterminada implementada por el kernel. A
cada señal se le asigna una de las siguientes conductas.
Los programadores pueden elegir implementar su propia conducta cuando se recibe una
señal específica. La respuesta del programa es completamente determinada por el
programador.
A no ser que la documentación del programa diga lo contrario, usted puede asumir que un proceso
responderá con la conducta implementada de kernel. Cualquier otra respuesta debe estar
documentada.
368
Uso de señales para terminar procesos
De las 32 señales utilizadas en Linux (y Unix) los usuarios normales en práctica (explícitamente)
sólo hacen uso de unas pocas.
Los usuarios estándar suelen utilizar señales para terminar un proceso (razón del nombre del
comando kill). Por convención, si los programadores quieren implementar la conducta
personalizada cuando se apaga (como por ejemplo botando memoria importante al disco, etc),
ellos implementan un manejador de señal personalizado de 15 para realizar la acción. El número
de señal 9 se maneja especialmente por el kernel y no puede anularse por un manejador de señal
personalizado o ser ignorado. Este se reserva como un último recurso, la técnica de nivel de kernel
para matar un proceso.
A manera de ejemplo, einstein iniciará un comando cat que en un principio se ejecutaría para
siempre. Luego traza el ID del proceso del comando y termina con un SIGTERM.
SIGTERM (número de señal 15) es la señal por defecto para el comando kill, por lo tanto einstein
pudo haber utilizado kill 8375 para el mismo efecto. A continuación, einstein repite la secuencia,
esta vez enviando un SIGKILL.
369
[einstein@station einstein]$ cat /dev/zero > /dev/null &
[1] 8387
[einstein@station einstein]$ ps
PID TTY TIME CMD
7985 pts/5 00:00:00 bash
8387 pts/5 00:00:01 cat
8388 pts/5 00:00:00 ps
[einstein@station einstein]$ kill -9 8387
[einstein@station einstein]$
[1]+ Killed cat /dev/zero >/dev/null
El uso de señales para controlar procesos es una ocurrencia tan común que las alternativas para
usar el comando kill abundan. Las siguientes secciones mencionan unas cuantas.
El comando pkill
En cada uno de los ejemplos anteriores, einstein necesita determinar el ID de un proceso antes de
enviar una señal a éste con el comandokill. El comando pkill se puede utilizar para enviar señales
a procesos seleccionados por medios más generales. El comando pkill espera la siguiente
sintaxis.
El primer símbolo especifica opcionalmente el número de señal para enviar (por defecto, el número
de señal 15). PATTERN es una expresión regular extendida que coincidirá con nombres de
comandos. El siguiente cuadro lista las opciones de comando más utilizadas. Los procesos que
cumplen con todos los criterios especificados enviarán la señal especificada.
Opción Efecto
-n Selecciona únicamente los procesos coincidentes iniciados más recientemente.
-u Selecciona procesos pertenecientes al usuario USER.
USER
-t TERM Selecciona procesos controlados por terminal TERM.
De manera conveniente, el comando pkill se omite a si mismo y la shell que lo inició cuando
mataba todos los proceso pertenecientes a un usurario particular o a una terminal. Considere el
siguiente ejemplo.
370
[maxwell@station maxwell]$ ps
PID TTY TIME CMD
10353 pts/4 00:00:00 bash
10396 pts/4 00:00:00 xclock
10397 pts/4 00:00:03 mozilla-bin
10422 pts/4 00:00:00 ps
[maxwell@station maxwell]$ pkill -u maxwell
[1]- Terminated xclock
[maxwell@station maxwell]$ ps
PID TTY TIME CMD
10353 pts/4 00:00:00 bash
10424 pts/4 00:00:00 ps
[2]+ Exit 15 mozilla
Observe que aunque la shell bash se clasifica como un proceso perteneciente al usuario maxwell,
ésta sobrevivió.
El comando killall
Igual que pkill, el comando killall envía señales a procesos especificados por el nombre de
comando. El comando killall soporta las siguientes opciones.
Opción Efecto
-i, --interactive De modo interactivo pregunta al usuario antes de enviar la señal a un proceso.
-w, --wait Espera hasta que todos los procesos estén muertos antes de retornar.
La aplicación del Monitor de sistema GNOME, presentada en una lección anterior, también puede
utilizarse para enviar señales a los procesos. Al hacer click derecho en un proceso, un menú
emergente le permite al usuario seleccionar End Process, el cual tiene el efecto de entregar un
SIGTERM al proceso. ¿Qué hace la opción del menú Matar proceso?
El comando top
El comando top puede también utilizarse para entregar señales a procesos. Al utilizar la tecla K,
aparece el siguiente diálogo encima de la lista de procesos, permitiéndole al usuario especificar
qué procesos ID deberían recibir la señal y qué señal entregar.
Ejemplos
371
Uso de señales para terminar procesos
Las señales suelen ser la única forma de terminar procesos que están siendo manejados por una
línea de comando de shell. Por ejemplo, los clientes (aplicaciones) gráficos X pueden matarse al
entregar un SIGTERM al proceso apropiado. En el siguiente ejemplo, el usuario maxwell está
ejecutando el navegador de red Mozilla y el reloj gráfico xclock. Utiliza el comando pgrep para
localizar sus ID de procesos, mata el primero mediante el comando kill y el segundo mediante el
comando pkill.
Pero, ¡espere! Hay una forma diferente para terminar aplicaciones gráficas aparte del envío de
señales. Solamente haga click en la casilla "cerrar" en la esquina superior derecha o seleccione
Cerrar en menú desplegable en la esquina superior izquierda. Entre bastidores, esta es
precisamente la labor de estas acciones: entregar una señal SIGTERM a una aplicación adjunta.
Cada vez que sea posible la señal SIGTERM debería utilizarse para terminar procesos. Sin
embargo, algunas veces, los procesos están "encerrados" y completamente insensibles, incluso
para las señales SIGTERM. En estos casos, la señal SIGKILL (número de señal 9) puede utilizarse
como un último recurso. La señal SIGKILL mata un proceso en el kernel sin ninguna interacción
con el proceso mismo.
A continuación, maxwell intenta terminar una simulación física (el proceso sim) con la señal por
defecto SIGTERM. Por alguna razón, el proceso es insensible por lo tanto maxwell lo mata con la
señal SIGKILL.
372
¡Hágalo que pare!
A continuación, maxwell observa primero cuántos procesos está ejecutando en la máquina local.
Luego mata todos los procesos.
Como resultado, maxwell se saca de la máquina (matando su propia sesión X o inicio de sesión de
consola virtual) y debe iniciar sesión otra vez.
Especificaciones
373
Control de trabajo
Conceptos clave
• La shell bash permite a los comandos ejecutarse en segundo plano como "trabajos".
• La shell bash permite a un trabajo ejecutarse en segundo plano y puede tener múltiples
trabajos en segundo plano.
• El comando jobs listará todos los trabajos en segundo plano.
• La secuencia de teclas CONTROL-Z suspenderá y enviará a segundo plano el actual
trabajo que se encuentra en primer plano.
• El comando bg reanuda un trabajo de segundo plano.
• El comando fg trae un trabajo de segundo plano a primer plano.
Discussion
Los temas tratados en este cuaderno hasta el momento, es decir la información sobre listado de
procesos, el cambio de un valor niceness de un proceso y el envío de señales a procesos son
características compartidas por todos los procesos, ya sean iniciados desde una línea de
comandos de shell o de otro modo. A diferencia de estos temas anteriores, el tema que nos resta,
control de trabajo tiene que ver el manejo de procesos iniciados desde un intérprete de comandos
de una shell interactiva y se enfocará en la shell bash.
Cuando se ejecuta un comando desde un intérprete de comandos shell bash, a no ser que usted
especifique lo contrario, el comando se ejecuta en el primer plano. La shell bash espera que el
comando de primer plano termine antes de expedir otro intérprete de comandos y cualquier cosa
escrita con el teclado se lee generalmente como la stdin para este comando. Todo esto debería
sonar familiar porque los comandos utilizados hasta el momento se han ejecutado en el primer
plano.
En contraste, cualquier comando que usted especifique puede también ejecutarse en el segundo
plano, adjuntándole el signo (“&”) a la línea de comandos. Por lo general, sólo los comandos de
larga ejecución que no requieren entradas desde el teclado y no generan grandes cantidades de
salida son apropiados para un segundo plano. Cuando la shell bash envía a segundo plano un
comando, el comando se conoce como un trabajo y se le asigna un número de trabajo.
En el siguiente ejemplo, einstein está realizando una búsqueda de los archivos que mayores de 1
megabyte en tamaño en su sistema de archivos. Dado que espera este comando para ejecutar por
un tiempo, dirige la stdout a un archivo, bota la stderr y la ejecuta como un trabajo de segundo
plano.
Después de iniciar el trabajo en el segundo plano, la shell bash reporta dos partes de información
a einstein. La primera es el número de trabajo reportado entre paréntesis cuadrados. La segunda
374
es el ID del proceso del trabajo de segundo plano. En este caso, el trabajo es el número de trabajo
1 y el ID del proceso del comando find es 7022.
Mientras que este comando se ejecuta en el segundo plano, einstein decide buscar los archivos
que le pertenecen y que no ha modificado en dos semanas. Escribe el comando apropiado find y
de nuevo envía a segundo plano el trabajo.
De nuevo, bash reporta el número de trabajo (2) y el ID del proceso del segundo comando find
(7023).
El segundo mensaje de shell bash está notificando a einstein el número de trabajo que se ha
terminado. La shell bash reporta que ésta ha salido con un código de retorno de 1 (opuesto a ser
matado por una señal) y revisualiza la línea de comando para recordar a einstein lo que ha
ejecutado. La shell bash no reporta inmediátamente la muerte de los trabajos, sino espera hasta la
próxima vez que interprete una línea de comandos.
Cuando einstein ha digerido todo esto sospecha que su segundo trabajo también ha terminado.
Simplemente, pulsa la tecla ENTER (para que bash "interpretará" la línea de comandos vacía).
Igualmente, la shell bash reporta su nuevo número de trabajo 2.
[einstein@station einstein]$
[2]+ Exit 1 find / -user einstein -and -mtime +14
>oldfiles.tx
t 2>/dev/null
El usuario einstein, al igual que maxwell, suele realizar cálculos físicos que toman mucho tiempo
para ejecutar. Inicia varias versiones de la simulación enviándolas al segundo plano.
[einstein@station einstein]$ ls
bin sim_a sim_b sim_c sim_d
[einstein@station einstein]$ ./sim_a &
[1] 7309
[einstein@station einstein]$ ./sim_b &
[2] 7311
[einstein@station einstein]$ ./sim_c &
[3] 7313
[einstein@station einstein]$ ./sim_d &
[4] 7315
375
El usuario einstein puede utilizar el comando incorporado jobs para reportar todos sus trabajos en
ejecución.
Cada uno de sus trabajos de segundo plano son listados junto con el número de trabajo. El trabajo
más reciente se conoce como el trabajo actual y es representado por el comando jobs con un “+”.
Un trabajo de segundo plano puede traerse al primer plano con el comando incorporado fg. El
comando fg espera un número de trabajo como un argumento o si ninguno es provisto pondrá el
trabajo actual en primer plano.
[einstein@station einstein]$ fg 3
./sim_c
Ahora, el trabajo sim_c está ejecutándose en el primer plano. Como consecuencia, la shell no
generará ningún intérprete de comandos cuando el proceso esté en ejecución.
376
[einstein@station einstein]$ fg 3
./sim_c
CTRL-Z
Cuando está suspendido (o para utilizar la terminología de shell, detenido), el proceso recibe el
número de trabajo (si es que aún no lo tiene) y se envía al segundo plano. El comando jobs
reporta el trabajo como un trabajo "detenido" y el comando ps confirma que está detenido.
Un trabajo detenido puede reiniciarse en el segundo plano con el comando incorporado bg. Al igual
que el comando fg, el comando bg espera un número de trabajo como un argumento o si no se
provee ninguno entonces se utiliza el trabajo actual.
[einstein@station einstein]$ bg 3
[3]+ ./sim_c &
[einstein@station einstein]$ jobs
[1] Running ./sim_a &
[2] Running ./sim_b &
[3]- Running ./sim_c &
[4]+ Running ./sim_d &
Matar trabajos
El comando kill, utilizado para entregar señales para procesos se implementa como un comando
incorporado de shell, (confusamente, también se encuentra otra versión en el sistema de archivos /
bin/kill. Probablemente usted está utilizando la versión de shell incorporada). Como resultado, está
consciente de los trabajos que la shell está administrando.
377
Cuando se especifica qué proceso debería recibir una señal, el número de trabajo del proceso (si lo
hay) puede especificarse en vez de su ID de proceso. Para distinguir los dos, los números de
trabajo están precedidos por un caracter de porcentaje (“%”) como se ilustra en el siguiente
ejemplo.
Aquí einstein erróneamente utilizó la sintaxis para especificar un ID de proceso, en vez del
número de trabajo. Puesto que él no posee su propio proceso con el ID de proceso número 2,
el comando falla.
Aquí, einstein utilizó la sintaxis correcta para especificar un número de trabajo y la señal fue
enviada al proceso sim_b.
Resumen
El siguiente cuadro resume los comandos y técnicas para administrar trabajos dentro de la shell
bash.
Comando Acción
trabajos Lista todos los trabajos
fg [N] Trae el trabajo N de segundo plano al primer plano (por defecto, el trabajo de segundo
plano "actual").
CTRL-Z Suspende y envía al segundo plano el actual comando de primer plano
bg [N] Inicia el trabajo de segundo plano detenido N (por defecto, el trabajo "actual"en
segundo plano).
kill %N Termina el trabajo de segundo plano N (enviando la señal SIGTERM).
Ejemplos
La discusión mencionó que los comandos se pueden iniciar en el segundo plano, agregando un
signo “&” a la línea de comandos. A continuación, einstein inicia un comando en el primer plano y
luego, dándose cuenta que le tomaría mucho tiempo completar, deseá haberlo iniciado en el
segundo plano.
378
[einstein@station einstein]$ ./sim_a
Con el fin de enviar al segundo plano el comando, primero lo suspende con la secuencia de control
CONTROL-Z, la cual lo abandona como un trabajo de segundo plano detenido. Luego reinicia el
trabajo en el segundo plano mediante bg.
Como una alternativa para el comando kill, la siguiente técnica se utiliza para cancelar trabajos
enviados al segundo plano. Primero, se trae el trabajo al primer plano con el comando y luego se
mata con la secuencia CONTROL-C.
Ejercicios en línea Lab Exercise Objetivo: Uso del control de trabajo bash para administrar
trabajos múltiples.Estimated Time: 10 mins.
Especificaciones
1. Inicie los siguientes cuatro comandos, colocando a cada uno en el segundo plano.
379
1. Cuatro trabajos enviados al segundo plano administrados por la shell bash. Los trabajos
cat y sleep deberían estar ejecutándose, mientras que los trabajos find y ls deberían
suspenderse
Después de haber calificado su ejercicio, utilice el comando kill (o la combinación fg/ CONTROL-
C) para matar todos los cuatro trabajos.
380
Programación de tareas retrasadas: at
Conceptos clave
Discussion
Demonios
Con un nombre inspirado por Daemon del físico Maxwell, los demonios Unix son procesos que se
ejecutan en el segundo plano, separados de una terminal, realizan tareas que no suelen estar
relacionadas con el teclado de un usuario. Los demonios suelen asociarse con servicios de red
tales como el servidor de red (httpd) o el servidor FTP (vsftpd). Otros demonios administran
tareas del sistema tal como el demonio de inicio de sesión (syslogd) y el demonio administrador
de potencia (apmd). Esta y la siguiente lección describirán dos demonios que permiten a los
usuarios retrasar tareas (atd), o ejecutar comandos en intervalos fijos (crond). Hasta el momento,
usted habrá notado una convención para nombres: los programas diseñados para ejecutarse como
demonios suelen terminar con la letra d.
Los demonios son procesos como cualquier otro proceso. Suelen iniciar como parte de la
secuencia de un sistema de arranque o por el usuario root, por lo tanto, usted nunca sabría que
están ahí a menos que los busque.
Algunos demonios se ejecutan como el usuario root, mientras otros adquieren la identidad de otro
usuario de sistema por asuntos de seguridad. Arriba, el demonio crond se está ejecutando como
root pero el demonio atd está ejecutándose como el demonio de usuario.
El demonio atd
El demonio atd le permite a los usuarios someter trabajos para ser realizados más tarde, tal como
a las "at 2:00am". Para utilizar el demonio atd, éste debe estar ejecutándose. Los usuarios pueden
confirmar que atd se está ejecutando simplemente al examinar la lista de procesos en ejecución:
381
[madonna@station madonna]$ ps aux | grep atd
daemon 4730 0.0 0.2 1420 532 ? S 15:42 0:00 /usr/sbin/atd
madonna 5570 0.0 0.2 3572 640 pts/2 S 16:43 0:00 grep atd
Observe que la séptima columna especifica con qué terminal se asocia un proceso. Para el
comando grep de blondie, la terminal es pts/2, la cual probablemente se refiere a una shell de red
o a una terminal gráfica dentro de una sesión X. Observe que el demonio atd no tiene terminal
asociada. Una de las características de un demonio es que quita su asociación con la terminal que
la inició.
El comando at se utiliza para someter trabajos al demonio atd para que se ejecuten en una hora
específica. Los comandos que se van a ejecutar son sometidos ya sea como script (con la opción -
f) o escritos directamente via la stdin. La salida estándar del comando se envía por correo al
usuario.
Opción Efecto
-f filename ejecuta el script especificado por el nombre de archivo
-m Notifica al usuario por correo electrónico cuando se ejecuta, incluso si no hay salida.
La hora del día se puede especificar utilizando HH:MM, con el sufijo "am" o "pm". Los términos en
inglés "midnight", "noon", y "teatime" también pueden utilizarse. Igualmente, mediante varios
formatos incluyendo MM/DD/YY. (mes/día/año/). Para mayor información refiérase a la página del
manual at(1).
El luchador hogan desearía imprimir un archivo con todo el correo que ha recibido de sus
admiradores, fanmail.txt. Está un poco preocupado porque comparte la impresora con ventura,
quien también utiliza mucho la impresora. Como quiere evitar peleas, decide demorar su trabajo de
impresión hasta las 2:00 de la mañana.
Dado que hogan no utilizó la opción -f, el comando at le pidió teclear sus comandos mediante la
stdin (el teclado). Afortunadamente, hogan sabía que cuando la secuencia CONTROL-D, se
escribe directamente desde una terminal indica un "fin de archivo". Como alternativa pudo haber
entubado el comando dentro de la stadin directamente:
382
[hogan@station hogan]$ at 2:00 am
warning: commands will be executed using (in order) a) $SHELL b) login shell c)
/bin/sh
at> lpr fanmail.txt
at> CTRL-D
job 7 at 2003-06-17 02:00
Por último, hogan recuerda que ventura está en vacaciones por lo tanto puede imprimir la
correspondencia de sus admiradores sin ningún problema. Decide cancelar su trabajo at e imprimir
el archivo directamente.
El comando batch, al igual que el comando at, se utiliza para retrasar tareas. A diferencia del
comando at, batch no ejecuta el comando at en un tiempo específico, sino que espera hasta que el
sistema se desocupe de otras tareas a cualquier hora. Si la máquina no está ocupada cuando se
somete un trabajo, el trabajo podría ejecutarse inmediatamente. El demonio atd controla el loadavg
(promedio de carga) del sistema y espera que baje por debajo de 0.8 antes de ejecutar el trabajo.
El comando batch tiene una sintaxis idéntica al comando at, donde los trabajos pueden ser
especificados con la stadin o sometidos como un lote con la opción -f. Si la hora se especifica, el
batch se demorará observando la máquina hasta el tiempo especificado. En ese momento batch
comenzará a controlar el loadavg del sistema, y ejecutará el trabajo cuando el sistema no esté de
otra manera ocupado.
El siguiente cuadro resume el comando utilizado al registrar trabajos con el demonio atd.
command uso
atd El demonio que ejecuta trabajos sometidos. Los usuarios no utilizan el comando atd
directamente.
at Somete trabajos al demonio atd para que se ejecuten en un tiempo específico.
batch Somete trabajos al demonio atd para que se ejecuten cuando el sistema no esté
ocupado.
atq Lista trabajos en espera con el demonio atd.
atrm Cancela un trabajo en espera con el demonio atd antes de ejecutarse.
383
Ejemplos
Dado que hogan no quiere teclear este comando y todas las opciones a cada rato, crea un guión
corto con el (o los) comando(s) que desearía ejecutar en un archivo llamado fanmail.at:
El usuario ventura ha notado que hogan tiene la costumbre de imprimir la correspondencia de sus
admiradores a las 2:00 am y como un chiste práctico decide someter un trabajo de su propiedad.
Crea el archivo bogus_fanmail.txt, que falsifica correspondencia no muy elogiosa de sus fanáticos.
Somete un trabajo que imprimirá el archivo a la 1:59 am confiando que hogan no notará la
inserción cuando recoja los papeles de la impresora en la mañana.
En cierto punto más adelante, el administrador del sistema de la máquina actuando como root,
observa los dos trabajos at en espera.
384
Curioso por lo que ventura piensa hacer, root fisgonea dentro del directorio spool de at. Examina el
contenido de su nombre de archivo spool llamado de forma críptica a0000c010c8887, el cual
pertenece al usuario ventura.
[root@station at]# ls -l
total 12
-rwx------ 1 hogan hogan 1480 Jun 17 12:37 a0000b010c8888
-rwx------ 1 ventura ventura 1459 Jun 17 13:08 a0000c010c8887
drwx------ 2 daemon daemon 4096 Jun 16 17:24 spool
[root@station at]# cat /var/spool/at/a0000c010c8887
#!/bin/sh
# atrun uid=511 gid=511
# mail ventura 0
umask 2
HOSTNAME=bowe-lt.rdu.redhat.com; export HOSTNAME
HISTSIZE=1000; export HISTSIZE
USER=ventura; export USER
LOGNAME=ventura; export LOGNAME
...
LESSOPEN=\|/usr/bin/lesspipe.sh\ %s; export LESSOPEN
G_BROKEN_FILENAMES=1; export G_BROKEN_FILENAMES
XAUTHORITY=/home/ventura/.xauthqEj97Q; export XAUTHORITY
cd /home/ventura || {
echo 'Execution directory inaccessible' >&2
exit 1
}
lpr bogus_fanmail.txt
(En este listado largo, se han borrado varias líneas y se han remplazado por "...".)
Al almacenar toda esta información con el trabajo sometido, el demonio atd es capaz de reconstruir
el entorno de ventura cuando se envía el trabajo. Si el trabajo enviado crea nuevos archivos, los
archivos tendrían los permisos esperados, porque el guión crearía la umask apropiada. Si
cualquiera de los comandos iniciados por el script dependiera de las variables de entorno, el
entorno se establecería como se espera y así sucesivamente.
(En este listado largo, se han borrado varias líneas y se han remplazado por "...".)
385
El archivo es un script de shell y debido a sus permisos pudo ejecutarse directamente.
La primera acción del script es la de establecer la umask del proceso a la umask de shell que
sometió el trabajo.
La segunda acción es inicializar una colección de variables de entorno para imitar el entorno
de shell que sometió el trabajo.
La tercera acción es cambiar el directorio actual del proceso al directorio actual de trabajo de
la shell que sometió el trabajo.
Por último, después de toda esta inicialización, el guión está listo para ejecutar el trabajo
sometido, en este caso lpr bogus_fanmail.txt.
Al almacenar toda esta información con el trabajo sometido, el demonio atd es capaz de reconstruir
el entorno de ventura cuando se envía el trabajo. Si el trabajo enviado crea nuevos archivos, los
archivos tendrían los permisos esperados, porque el guión crearía la umask apropiada. Si
cualquiera de los comandos iniciados por el script dependiera de las variables de entorno, el
entorno se establecería como se espera y así sucesivamente.
Ejercicios en línea
Ejercicio Objetivo: Utilizar el servicio atd para retrasar la ejecución de una tarea.
Especificaciones
Usted ha tenido dificultades tratando de recordar qué día es y por lo tanto quisiera enviarse una
copia del calendario actual para verlo como primera cosa en la mañana. Envía un trabajo que
simplemente ejecuta el comando cal para las 3:45 de la mañana. Asegúrese que es el único
trabajo programado con esa facultad.
Un trabajo en espera que generará la salida del comando cal a las 3:45 de la mañana.
386
Programación de tareas periódicas: cron
Conceptos clave
Discussion
A menudo, las personas encuentran que están realizando tareas en forma sistemática. En la
administración de sistemas dichas tareas podrían incluir quitar archivos viejos o no utilizados del
directorio /tmp o comprobar si un archivo que está recolectando mensajes de registro no ha crecido
demasiado. Otros usuarios podrían hallar que son tareas propias el chequear archivos grandes que
ya no se estén utilizando o chequear un sitio web para ver si hay algún anuncio.
El servicio cron permite a los usuarios configurar comandos para que se ejecuten con regularidad
tal como cada 10 minutos, una vez cada jueves, o dos veces al mes. Los usuarios especifican qué
comandos deberían ejecutarse y a qué horas mediante el comando crontab para configurar su
"cuadro cron". Las tareas se administran por el demonio tradicional de Linux (y Unix), el demonio
crond.
El servicio cron
El demonio crond es el demonio que realiza tareas periódicamente en nombre del sistema o de
usuarios individuales. El demonio suele iniciarse cuando el sistema arranca, por lo tanto, la
mayoría de usuarios lo pueden ignorar. Al listar todos los procesos y buscar crond puede confirmar
si el demonio crond está en ejecución.
Sintaxis crontab
Los usuarios especifican los trabajos que se van a ejecutar y cuándo se van a ejecutar, al
configurar un archivo conocido como el "cuadro cron" a menudo abreviado en inglés "crontab". Un
ejemplo de archivo crontab aparece a continuación.
387
# set the default language to be english
LOCALE=en_US
05 * * * * procinfo
15 04 * * * find $HOME -size +100k
25 04 1 * * echo "Pay your bills"
35 04 14 3 * echo "Beware the Ides of March" | mail -s "a warning" julius
45 04 * * 1 find $HOME -atime +30 | lpr
Un archivo crontab es un archivo de configuración basado en línea, cada línea realiza una de tres
funciones:
Comentarios
Todas las líneas cuyo primer caracter (no espacio) es # se consideran comentarios y se
ignoran.
Variables de entorno
Todas las líneas que tienen la forma nombre = valor se utilizan para definir variables de
entorno.
Comandos cron
Cualquier otra línea (no en blanco) se considera un comando cron, el cual consta de seis
campos descritos a continuación.
Las líneas del comando cron constan de seis campos separados de espacios en blanco. Los
primeros 5 campos se utilizan para especificar cuándo ejecutar el comando y el sexto campo se
utiliza para especificar el comando a ejecutar (compuesto de todo después del quinto campo). Los
primeros cinco campos especifican la siguiente información:
,----------------> minute
| ,-------------> hour
| | ,----------> day of month
| | | ,-------> month (1=January, 2=February, ...)
| | | | ,----> day of week (0=Sunday, 1=Monday, ...)
| | | | | ,-> command to run
| | | | | |
25 04 1 * * echo "Pay your bills"
Cada uno de los primeros cinco campos debe llenarse con un símbolo mediante la siguiente
sintaxis:
388
después de la hora)
Los usuarios rara vez administran su archivo crontab directamente (o incluso saben dónde se
almacena), en cambio, utilizan el comando crontab para editar la lista o quitarla.
crontab ARCHIVO
Edita o quita el archivo crontab actual o remplaza el archivo actual crontab con FILE.
Opción Efecto
-e modifica el archivo actual
-l lista el archivo actual
-r quita el archivo actual
05 * * * * procinfo
15 04 * * * find $HOME -size +100k
25 04 1 * * echo "Pay your bills"
35 04 14 3 * echo "Beware the Ides of March" | mail -s "a warning" julius
45 04 * * 1 find $HOME -atime +30 | lpr
[hogan@station hogan]$ crontab -l > mycopy
Luego, hogan quita su configuración de crontab actual. Cuando trata de nuevo de listar la
configuración, se le informa que no existe ninguna configuración actual.
Con el fin de restaurar su configuración cron, hogan utiliza el comando crontab una vez más, esta
vez especificando el archivo mycopy como un argumento. Tras listar su configuración una vez más,
halla que su actual configuración fue leída desde el archivo mycopy.
389
Un poco molesto, el banner se ha duplicado en el proceso, ¿sabe por qué?
05 * * * * procinfo
15 04 * * * find $HOME -size +100k
25 04 1 * * echo "Pay your bills"
35 04 14 3 * echo "Beware the Ides of March" | mail -s "a warning" julius
45 04 * * 1 find $HOME -atime +30 | lpr
[hogan@station hogan]$ rm mycopy
7 2003-06-17 02:00 a hogan
Los usuarios suelen modificar sus archivos crontab mediante crontab -e. El comando crontab
abrirá la configuración crontab dentro del editor predeterminado del usuario. Cuando el usuario
termina de modificar el archivo y sale del editor, el contenido modificado del archivo se instala
como la nueva configuración crontab.
El editor por defecto es /bin/vi, sin embargo,crontab, al igual que otros comandos, examina la
variable de entorno EDITOR. Si la variable se ha establecido, se utilizará para especificar el editor
que se va a abrir. Por ejemplo, si hogan prefiere utilizar el editor nano, primero puede configurar la
variable de entorno EDITOR como /usr/bin/nano (o simplemente nano) y luego ejecutar crontab -
e.
Si hogan quisiera utilizar nano como su editor podría utilizar uno de los siguientes métodos:
o aún mejor, hogan pudo agregar la línea "export EDITOR=nano" a su archivo .bash_profile y la
variable de entorno se establecería automáticamente cada vez que inicie sesión.
390
1. Crear un archivo de texto que contenga su configuración deseada y luego instalarlo con
crontab FILENAME.
2. Editar su configuración establecida con crontab -e.
¿A dónde va la salida?
¿Cómo recibe el usuario la salida de los comandos que cron ejecuta? El demonio enviará por
correo la stdout y el stderr de todos los comandos ejecutados al usuario local. Suponga que
ventura configuró el siguiente trabajo cron:
05 * * * * cal
Una vez por hora, a la hora y cinco minutos espera recibir un nuevo correo como el siguiente:
June 2003
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
El mensaje del correo contiene la salida del comando en el cuerpo y todas las variables de entorno
en los encabezados.
Opcionalmente, ventura podría haber definido la variable de entorno especial MAILTO a una
dirección de correo electrónico y el correo sería enviado a esa dirección en su lugar:
05 * * * * cal
Al configurar trabajos cron, los usuarios deberían tener en cuenta un detalle. Cuando el demonio
crond inicia el comando del usuario, éste no ejecuta el comando desde la shell sino que bifurca y
exec el comando directamente. Esto tiene una implicación importante: cualquier variable de
entorno o alias configurados por la shell en el arranque tal como cualquiera que esté definida en
/etc/profile o ~/.bash_profile, no estarán disponibles cuando cron ejecute el comando.
391
Si un usuario quiere que una variable de entorno esté definida necesita explícitamente definir la
variable en su configuración crontab.
Ejemplos
(... while in the text editor, ventura adds the following line...)
ventura ahora puede esperar recibir correo electŕonico, conteniendo una versión formateada de
texto de la página web de formación de Red Hat cada mañana a las 5:00.
Luego, ventura se da cuenta que ha tenido la mala costumbre de crear archivos muy grandes y
luego los olvida. Con el fin de ayudarse a recordar los archivos grandes que está dejando atrás,
configura un trabajo cron el cual le enviará cada domingo un correo con una lista de todos los
archivos mayores de 100k.
392
[ventura@station ventura]$ crontab -e
no crontab for ventura - using an empty one
(... within the text editor, ventura adds the following line...)
Ahora, los domingos a las 5:10 de la mañana, ventura puede esperar recibir un correo electrónico
listando todos los archivos mayores de 100 K bajo su directorio de inicio.
Continuando con sus esfuerzos de no desperdiciar espacio duro, ventura desearía crear
regularmente una lista separada de archivos a los que no haya tenido acceso reciéntemente y
recibir esta lista al mismo tiempo que recibe su lista de archivos grandes. En lugar de complicar su
archivo cron, crea un guión llamado cron.weekly, lo coloca en el subdirectorio bin y lo hace
ejecutable.
echo
echo "==== files not used in the past month ====="
find $HOME -atime +30
393
[ventura@station ventura]$ crontab -e
(... within the text editor, ventura edits the following line ...)
05 05 * * 0 bin/cron.weekly
Ahora en lugar de mantener su configuración crontab, ventura puede apenas modifica el script
cron.weekly.
Impresión de fanmail
El usuario hogan ha llegado al punto donde imprime el archivo que recoge la nueva
correspondencia de los admiradores, fanmail.txt, cada lunes, miércoles y viernes. Decide utilizar el
servicio cron para automatizar el proceso.
Debido a que esta es la primera vez que utiliza cron, él no tiene que preocuparse por la posibilidad
de remplazar trabajos ya existentes. Entonces configura un archivo cron localmente. Mediante un
editor de texto, crea el archivo crontab.hogan en su directorio de inicio. Luego instala el archivo con
el comando crontab.
Ahora espera que su archivo de correspondencia de sus admiradores sea impreso los lunes,
miércoles y viernes en las tardes a la 1:45. Cuando se imprimen las primeras copias se envían a la
impresora que no es, hogan nota que su .bash_profile configura su variable de entorno PRINTER
para cola de espera local, hp-color, automáticamente cuando inicia sesión. Sin embargo, como
cron no utiliza una shell para ejecutar trabajos cron, la variable de entorno de inicio sesión no se
está configurando. Edita crontab.hogan para definir explícitamente y vuelve a someter el archivo
con crontab.
394
[hogan@station hogan]$ cat crontab.hogan
PRINTER=hp-color
45 13 * * 1,3,5 lpr fanmail.txt
[hogan@station hogan]$ crontab crontab.hogan
395
Ejercicios en línea
Control de quién está en el sistema. Ejercicio en línea Objetivo: Configurar un trabajo cron
Está un poco paranóico y quiere controlar quién está usando su computador en la noche. Configura
un trabajo cron que le enviará por correo la salida del comando who diariamente a las 4:35 de la
mañana.
1. Una configuración cron que envía por correo la salida del comando who diariamente a las
4:30 am.
396
Network Applications
Introducción a las redes TCP/IP
Conceptos clave
• La mayoría de los servicios de redes de Linux están diseñados en torno a una relación de
cliente servidor.
• Las aplicaciones de servidor de red generalmente están diseñadas para permanecer
"siempre en ejecución" iniciándose automáticamente cuando el sistema arranca y
apagándose solamente cuando el sistema lo hace. Por lo general, sólo el usuario root
puede administrar procesos del servidor.
• Las aplicaciones de cliente de red suelen ejecutarse únicamente cuando están en uso y las
puede iniciar cualquier usuario.
• La mayoría de los servidores de red Linux y clientes se comunican mediante el
protocoloTCP/IP.
• La dirección TCP/IP tanto del proceso del cliente como del proceso del servidor consta de
una dirección IP y de un puerto.
• Los servidores de red suelen utilizar puertos asignados denominados puertos "bien
conocidos" como se catalogan en el archivo /etc/services. Los clientes de red suelen
utilizar puertos privilegiados de modo aleatorio. A menudo, los puertos bien conocidos
residen en el rango de puertos privilegiados por debajo del puerto número 1024.
• El comando hostname puede utilizarse para examinar la dirección IP actual de la máquina,
mientras que el comando netstat -tuna se puede utilizar para examinar todos los puertos
abiertos.
Discussion
Iniciaremos nuestro cuaderno sobre las aplicaciones de redes con la introducción a los conceptos
de clientes y servidores y los aspectos básicos del protocolo TCP/IP. Hablaremos del protocolo
TCP/IP como si fuera el único protocolo disponible en Internet. Este no es el caso pero es el
protocolo más utilizado y los conceptos necesarios para entender se amplían (o reducen) de forma
natural a los otros protocolos.
La mayoría de las aplicaciones de redes actuales están diseñadas en torno a la relación cliente-
servidor. El cliente de red suele ser una aplicación que actúa en nombre de una persona que está
tratando de realizar alguna tarea en particular tal como navegar en una URL o ejecutar el comando
rdate para preguntar la hora actual a un servidor de tiempo. El servidor de red suele ser una
aplicación que ofrece servicios, tales como entregar el contenido de las páginas web o dar la hora
actual.
El diseño de (aplicaciones que actúan como) clientes de red y (aplicaciones que actúan como)
servidores de red difiere dramáticamente. Con el fin de apreciar las diferencias, los compararemos
con los agentes en una relación cliente-servidor, un cliente comprando una barra de caramelo a un
vendedor.
El servidor
Los vendedores y los servicios de red efectivos comparten las siguientes características.
397
Los servidores están altamente disponibles
Así como un vendedor siempre debe utilizar la registradora, incluso cuando no hay clientes, los
procesos que ejecutan servicios de red necesitan estar ejecutándose, listos para suplir los servicios
cuando se soliciten. Por lo general, los procesos que ejecutan servicios de red se inician en el
momento de arranque y continúan ejecutándose hasta que la máquina sea apagada. En Linux (y
Unix) dichos procesos se conocen como demonios. Por lo general, sólo el usuario root puede
iniciar o cerrar procesos que funcionan como servidores de red.
Además de estar disponibles cuando un cliente necesita el servicio, los vendedores se están dónde
saben que los clientes los pueden encontrar. Así como los clientes pueden buscar la ubicación de
vendedores de caramelos desconocidos, en los directorios telefónicos y encontrarlos por dirección
postal, los clientes de red pueden ubicar servidores de redes desconocidas mediante un hostname,
el cual se convierte en la dirección IP utilizada para tener acceso al servicio.
El cliente
Por el contrario, el cliente de la tienda de caramelos no necesita estar ni altamente disponible ni ser
muy conocido. Un cliente no se estará en una tienda de caramelos todo el día por si decide
comprar un caramelo. Del mismo modo, los clientes no necesitan permanecer en sitios bien
conocidos. Nuestro cliente no se queda todo el día en casa por si alguien pasa a venderle una
barra de caramelo.
Los procesos que ejecutan clientes de red son iniciados por usuarios normales y por lo general se
ejecutan todo el tiempo necesario para completar una tarea. Cuando alguien hace un receso para ir
a almorzar, cierra su navegador de red. Además, las aplicaciones de cliente no necesitan tener
direcciones fijas, pueden moverse de un lugar a otro. Más adelante veremos esto detalladamente.
Direcciones TCP/IP
Todo proceso que participa en una conversación TCP/IP debe tener una Dirección IP, así como
cada participante en una conversación debe tener un número telefónico. Además, todo proceso en
una conversación TCP/IP debe tener un número de puerto, cuya analogía más cercana podría ser
una extensión telefónica asociada a un número de teléfono.
Los computadores en una red se identificans con una dirección IP. La dirección IP viene en forma
de cuatro números enteros, cada uno en un rango de 0 a 255 (no es una coincidencia que la
cantidad de información pueda codificarse en un byte de memoria) y tradicionalmente separados
por puntos así como 192.168.0.3. Esta representación suele conocerse de modo informal como un
quad punteado.
Los procesos en computadores se identifican con unnúmero de puerto, el cual es un entero entre 1
y 65535 (no es una coincidencia que la cantidad de información se codifique en 2 bytes de
memoria). Cada vez que un proceso quiere participar en una conversación TCP/IP con otro
proceso, el kernel debe asignarle primero un número de puerto.
El protocolo TCP/IP permite dos procesos, para localizarse entre sí, cada uno se identifica con una
dirección IP y un número de puerto. La dirección IP sirve para localizar la máquina en la que el
proceso se está ejecutando (esta es la "parte del protocolo IP") y el número de puerto se utiliza
para localizar el proceso correcto en la máquina (esta es la parte "TCP").
398
Sockets
Con el fin de ilustrar una transacción típica TCP/IP, examinaremos la conversación entre el
navegador de red mozilla de un estudiante fictisio ejecutándo en la máquina
station3.example.com, lo que se traduce en una dirección IP 123.45.67.89 y el servidor de red
httpd ejecutando en academy.redhat.com, lo que se traduce en una dirección IP de 66.187.232.51.
El proceso suele parecerse a lo siguiente.
Una vez se establece el socket, los procesos mozilla y httpd pueden leer información con read y
escribir a un archivo con write de un modo tan sencillo como leer y escribir desde un archivo,
(recuerde ..."todo es un archivo", incluyendo las conexiones de red! Para fines más prácticos, un
socket es sólo otro descriptor de archivo). Los verbos resaltados en esta sección bind (unir), listen
(escuchar), connect (conectar), accept (aceptar), e inclusoread (leer) y write (escribir) son
términos bien definidos en Linux (y Unix). También son los nombres de llamadas al sistema de
programación que realizan cada paso.
399
Figure 2. Múltiples sockets TCP/IP
En nuestro ejemplo, mencionamos que el proceso httpd solicitó bind al puerto 80, y en retorno, el
proceso mozilla solicitó connect al puerto 80 del servidor. ¿Cómo se convino que el puerto 80 era
el apropiado para el servidor de red? Los servicios de Internet tradicionales tales como el servidor
de red o el servidor ftp o el servidor smtp (de correo electrónico), se conocen como servicios bien
conocidos. En máquinas de Linux y (Unix), el catálogo de servicios bien conocidos, y los puertos
asignados a ellos se mantienen en el archivo /etc/services.
Observe que tanto el cliente como el servidor necesitan concordar con el número apropiado de
puerto para que el archivo /etc/services sea tan importante en la máquina del cliente como en la del
servidor. El sólo hecho de que un servicio se liste en el archivo /etc/services no significa que usted
está ejecutando (o incluso siendo capaz de ejecutar) ese servicio bien conocido.
Puertos privilegiados
A diferencia de los clientes, los procesos que ejecutan servidores de red suelen solicitar el puerto al
que quieren vincularse. Solamente un proceso puede vincularse a un puerto en un tiempo
determinado (¿A qué se debe esto?) Los puertos menores de 1024 se conocen como puertos
privilegiados y son tratados de modo especial por el kernel. Únicamente los procesos ejecutándose
como el usuario root pueden enlazarse a puertos privilegiados, (esto ayuda a asegurar que si elvis
tuviera una cuenta en la máquina academy.redhat.com, no podría iniciar una versión falsa de un
servidor de red que podría distribuir información falsa). En un principio, los puertos bien conocidos
y los puertos con privilegios pretendian coincidir pero en la práctica hay más puertos bien
conocidos que privilegiados.
400
Determinar los servicios actuales de red TCP/IP
El comando hostname, sin argumentos, muestra el nombre del equipo de la máquina actual. Con
la opción -i, la dirección IP de la máquina se visualiza en su lugar.
El diseño del comando hostname es un poco equívoco, porque las máquinas pueden tener
fácilmente más de una dirección IP (una para cada red múltiple de tarjetas de interfaz, por
ejemplo). En dichas situaciones, no hay razón para que cualquier dirección IP tenga prioridad
sobre las otras. No obstante, por razones históricas, el kernel mantiene el rastro de un
parámetro conocido como su nombre del equipo y el comando hostname -i presenta la
dirección IP asociada con éste.
Cuando un puerto es utilizado por un socket se le conoce como puerto abierto. El comando netstat
sirve para ver una variedad de información de redes incluyendo los puertos abiertos.
Infortunadamente, cuando un comando es llamado sin ninguna opción la salida del comando
netstat se inunda de información poco interesante, sockets locales "Unix" utilizados para
comunicarse entre procesos en la misma máquina. Sin embargo, cuando se llama con las
siguientes opciones se ve información más interesante.
Opción Efecto
-t Presenta los sockets TCP
-u Presenta los sockets UDP
-n Presenta la dirección IP en lugar del hostname
-a Presenta todos los sockets incluso aquellos en estado LISTEN
Muchas más opciones están disponibles, para mayor información acuda a la página de manual
netstat(8). Las siguientes opciones se escogieron, no solo porque cuando se combinan producen
una salida interesante, sino porque también son fáciles de recordar: por ejemplo, "tuna" (atún).
401
Cuando se invoca con las siguientes opciones, la salida de netstat es similar a la siguiente.
El diseño del comando hostname es un poco equívoco, porque las máquinas pueden tener
fácilmente más de una dirección IP (una para cada red múltiple de tarjetas de interfaz, por
ejemplo). En dichas situaciones, no hay razón para que cualquier dirección IP tenga prioridad
sobre las otras. No obstante, por razones históricas, el kernel mantiene el rastro de un
parámetro conocido como su nombre del equipo y el comando hostname -i presenta la
dirección IP asociada con éste.
Cuando un puerto es utilizado por un socket se le conoce como puerto abierto. El comando netstat
sirve para ver una variedad de información de redes incluyendo los puertos abiertos.
Infortunadamente, cuando un comando es llamado sin ninguna opción la salida del comando
netstat se inunda de información poco interesante, sockets locales "Unix" utilizados para
comunicarse entre procesos en la misma máquina. Sin embargo, cuando se llama con las
siguientes opciones se ve información más interesante.
402
Table 1. Opciones para el comando netstat
Opción Efecto
-t Presenta los sockets TCP
-u Presenta los sockets UDP
-n Presenta la dirección IP en lugar del hostname
-a Presenta todos los sockets incluso aquellos en estado LISTEN
Muchas más opciones están disponibles, para mayor información acuda a la página de manual
netstat(8). Las siguientes opciones se escogieron, no solo porque cuando se combinan producen
una salida interesante, sino porque también son fáciles de recordar: por ejemplo, "tuna" (atún).
Cuando se invoca con las siguientes opciones, la salida de netstat es similar a la siguiente.
403
Direcciones especiales IP
Las siguientes direcciones IP pueden hallarse en la columna de dirección local de la salida anterior.
Dirección Función
IP
172.16.62.9 La dirección IP externa de la máquina tal como la reportó el comando hostname -i.
127.0.0.1 La dirección bucle local. Cada máquina que utiliza las redes TCP/IP es compatible
con la dirección de bucle local o loopback. Las conexiones a la máquina o desde la
máquina desde esta dirección siempre se retroalimentan a la máquina local para que
la comunicación pueda ocurrir entre dos procesos en la misma máquina. La
conversación que se presenta sobre la dirección de bucle local ocurre internamente,
no se expone a la red.
0.0.0.0 Esta dirección especial IP sirve para referirse a "todas" las direcciones IP
disponibles. Cuando un proceso se enlaza a un determinado puerto, puede elegir
entre utilizar únicamente una dirección particular externa, sólo la dirección de bucle
local o todas las direcciones IP disponibles.
Sockets de escucha
Los sockets de escucha son conexiones pertenecientes a un servidor antes de que los clientes se
presenten. Por ejemplo, al final del primer paso de nuestra conexión TCP/IP de muestra anterior, el
proceso httpd tendría una conexión abierta en el estado de escucha. Observe en la salida anterior
que para las conexiones de escucha, sólo se define la mitad de la dirección.
Conexiones establecidas
Como su nombre lo implica, los sockets establecidos tienen un proceso de cliente y un proceso de
servidor con comunicación establecida.
Uniendo esfuerzos
Ahora podemos reunir algunas de las partes para analizar unas pocas líneas extraídas de la salida
anterior.
Este socket está conectado a todas las interfaces en el puerto 80 en el estado de ESCUCHA.
Aparentemente esta máquina también tiene un servidor de red httpd escuchando activamente
conexiones de clientes.
Estos dos sockets están escuchando conexiones, pero sólo en la dirección de bucle local. Deben
pertenecer a servicios que esperan recibir conexiones desde otros procesos en la máquina local
404
pero no desde la red. Para determinar a qué servicios pertenecen estos puertos ejecutamos un
grep desde el archivo /etc/services.
Aparentemente, cualquier proceso que haya solicitado el puerto 25 está escuchando clientes de
correo electrónico. Probablemente es el demonio sendmail. El proceso de escucha en el puerto
631 está escuchando clientes de impresión. Probablemente es el demonio de impresión cupsd.
Ambos servicios se tratarán más adelante en este cuaderno.
Nuestra línea extraída representa una conexión establecida entre lo que aparentemente es un
cliente en nuestra máquina local, conectado al servicio enlazado al puerto 22 en nuestra máquina
remota. De nuevo, trataremos de llamar a grep para buscar el servicio bien conocido asociado con
el puerto 22.
Aparentemente, esta línea representa una conexión activa entre un cliente ssh en la máquina local
y un demonio sshd en una máquina con una dirección IP de172.16.62.8.
Ejercicios en línea Lab Exercise Objetivo: Familiarizarse con la configuración y actividad TCP/IP.
Estimated Time: 10 mins.
Especificaciones
405
2. Crear el archivo ~/lab11.1/listening_ports que contenga una lista de todos los puertos
menores que 1024 en su máquina actual, abiertos en el estado de escucha, un puerto por
línea.
406
Impresión Linux
Conceptos clave
• Linux de Red Hat Enterprise utiliza el sistema de impresión CUPS para administrar
impresoras.
• El sistema de impresión CUPS está diseñado en torno al concepto de cola de impresión, el
cual combina un directorio de almacenamiento temporal, un filtro y un dispositivo de
impresión.
• Los comandos gnome-print-manager y lpstat pueden utilizarse para navegar colas de
impresión disponibles.
• Los comandos lpr, lpq y lprm se utilizan para someter ("solicitar") trabajos de impresión,
averiguar por trabajos importantes y quitar trabajos de impresión pendientes,
respectivamente. Todos examinarán la variable de entorno PRINTER para determinar la
cola de impresión por defecto.
• Los comandos lp y cancel se comportan de un modo similar a los comandos lpr ylprm.
• Muchas aplicaciones imprimen por entubamiento a stdin de una línea de comando
personalizable lpr.
Discussion
Introducción a CUPS
Linux de Red Hat Enterprise utiliza el Sistema de Impresión Común de Unix (CUPS) para
administrar impresoras. En lugar de interactuar con la impresora directamente, los usuarios
someten las solicitudes de impresión a las colas de impresión que son manejadas por el demonio
cupsd. Las solicitudes de impresión pendientes en una cola de impresión se conocen como
trabajos de impresión. Una vez se ha sometido el trabajo a la cola, los usuarios pueden retornar
rápidamente a cualquiera de las tareas que estaban haciendo. Si la impresora está ocupada con
otro documento o no tiene papel, o no está disponible en la red, el demonio cupsd controlará la
situación y enviará (o reenviará) el trabajo de impresión a la impresora cuando quede disponible.
El demonio cupsd utiliza el Protocolo de Impresión de Internet (IPP), el cual es una extensión
directa del protocolo HTTP, diseñado para permitir administración de cola de impresión, a la
manera de un sistema operativo independiente. Como resultado, la administración de CUPS tiene
mucho en común con la administración del servidor de red.
La siguiente gráfica identifica los elementos que participan en la impresión Linux; dichos elementos
se tratan en detalle más adelante.
407
Colas de impresión
La tarea fundamental que enfrenta el administrador al configurar Linux de Red Hat Enterprise para
que utilice una impresora particular o un servicio de red de impresión, es definir y nombrar
correctamente la cola de impresión para el recurso. Esto generalmente implica identificar cuáles de
los dispositivos secundarios anteriores se utilizan para acceder al dispositivo, elegir un filtro
apropiado para el dispositivo, llamar y activar la cola de impresión.
En este curso asumiremos que ya se ha hecho todo el trabajo difícil y que las colas de impresión
disponibles para su sistema ya se han definido.
408
Navegar las colas de impresión disponibles: gnome-print-manager y lpstat
Las colas de impresión están disponibles ya sea porque se han definido en la máquina local o
descubierto mediante la habilidad de CUPS para navegar la red local para impresoras publicadas.
Cuando el entorno gráfico no está disponible, o incluso cuando lo está, el comando lpstat se puede
utilizar para escanear las colas de impresión disponibles desde la línea de comando. La siguiente
línea de comandos sirve para clasificar el comando lpstat.
Opción Efecto
-a Lista estado de aceptación de todas las colas de impresión.
-o Lista todos los trabajos importantes
-p Lista todas las colas de impresión y si están inactivas u ocupadas.
-s Lista el estatus de la impresora, incluída la cola por defecto y el dispositivo secundario
asociado con cada cola.
Para mayor información, vea la página de manual lpstat(1). A continuación, elvis descubre que su
cola de impresión de sistema por defecto, se llama simplemente "printer" y que tiene varias colas
de impresión disponibles, que parecen referirse a la cola de impresión IPP en un servidor de
impresora local.
CUPS utiliza los comandos de UNIX tradicionales para interactuar con el sistema de impresión: lpr
somete archivos e información que van a imprimirse, lpq examina el estatus de trabajos de
impresión importantes y lprm quita trabajos de impresión pendientes en la cola. Todos los tres
comandos utilizan las siguientes técnicas para especificar qué cola de impresión utilizar en el orden
especificado.
409
3. De otra manera, se utiliza el sistema de cola de impresión por defecto.
Los trabajos pueden someterse con el comando lpr. Todos los argumentos son interpretados como
archivos para someter. Si no se especifican argumentos en su lugar se lee la entrada estándar. Las
siguientes opciones sirven para clasificar el comando lpr.
Opción Efecto
-P Uso de la cola de impresión impresora.
impresora
-# Imprime # copias
-p Representa archivos de texto con un encabezado que contiene el nombre del
archivo, nombre del trabajo y el sello de fecha.
-r Borra los archivos de impresión nombrados después de imprimir.
A manera de ejemplo, a continuación, blondie utiliza el comando lpr para imprimir el archivo
README mediante la cola de impresiónsales.
El comando lpq lista los trabajos pendientes en una cola. En el siguiente ejemplo, blondie somete
la salida del comando df para la impresora legal y luego examina el contenido de la cola.
Blondie sospecha que algo anda mal con la impresora legal y decide iniciar utilizando la impresora
sales como su impresora por defecto. Primero configura la variable de entorno PRINTER para
reflejar sus nuevas preferencias, luego utiliza el comando lprm para quitar su trabajo de la cola
legal.
410
[blondie@station blondie]$ export PRINTER=sales
[blondie@station blondie]$ lpq
sales is ready
no entries
[blondie@station blondie]$ lpq -P legal
legal is ready and printing
Rank Owner Job File(s) Total Size
active elvis 1 services 20480 bytes
1st blondie 5 (stdin) 1024 bytes
[blondie@station blondie]$ lprm 5
[blondie@station blondie]$ lpq -P legal
legal is ready and printing
Rank Owner Job File(s) Total Size
active bowe 1 services 20480 bytes
[blondie@station blondie]$ df | lpr
Observe que en el primer comando lpq y el último comando lpr, la variable de entorno PRINTER
implícitamente especificó la cola de impresión sales.
Ya hemos visto que lpstat es compatible y es la herramienta preferida para descubrir colas de
impresión. Los comandos lp y cancel también están disponibles como variaciones leves de los
comandos lpr y lprm. Para mayor información, consulte la página de manual lp(1).
Con frecuencia las aplicaciones Linux suelen imprimir entubando la información directamente a la
entrada estándar del comando lpr. Por lo general, las aplicaciones permiten a los usuarios
personalizar la línea de comando lpr, para que, por ejemplo, se pueda especificar una cola de
impresión diferente a la cola de impresión por defecto.
Por último, seríamos negligentes si abandonáramos el tema de CUPS sin mencionar la interfaz de
red nativa que el demonio cupsd brinda. Como se mencionó, la mayoría de los clientes interactúan
con el demonio cupsd mediante el protocolo IPP, el cual es una extensión del protocolo HTTP.
Debido a su parecido, el demonio cupsd se comporta en muchas formas como el demonio de web,
incluyendo el servidor de las páginas de administración de estilo CGI.
411
Con el fin de ver las páginas de administración de CUPS, apunte un navegador de red hacia la
dirección de la máquina local, pero sobreescriba el puerto 80 por defecto con el puerto de servicio
bien conocido de los demonios de CUPS, 631.
http://localhost:631
El demonio cupsd retornará con una"página de inicio" de CUPS desde donde pueden verse las
impresoras y los trabajos de impresión y existe dsiponible una copiosa documentación en línea.
Ejercicios en línea
Lab Exercise
Configuración
Su estación debería configurarse con una cola de impresión llamada rha_faux. Esta cola de
impresión se anexa a la impresora virtual en ejecución en el servidor del aula de clase. Usted
puede ver la primera página de cualquier trabajo de impresión enviado a la impresora en el
classroom server.
Especificaciones
412
Administración de archivos de impresión
Conceptos clave
Discussion
PostScript
En Linux, la mayoría de las impresoras esperan recibir texto ASCII o gráficas mediante el formato
PostScript. A diferencia de la mayoría de los formatos gráficos, PostScript es un lenguaje de
guiones de gran alcance, el cual se ha adaptado a la tarea de traducir gráficas en la página
impresa. La sofisticación del lenguaje PostScript le permite realizar trabajos complejos, pero debe
utilizar un intérprete para entregar archivos PostScript como imágenes.
Cuando se invoca como el comando gs, el intérprete Ghostscript puede utilizarse para traducir
archivos PostScript directamente en la pantalla. Por ejemplo, en el siguiente diálogo, al navegador
de red mozilla se le pide imprimir la página web actual no a una cola de impresión, sino a un
archivo PostScript titulado output.ps.
Como lo ilustra el comando head, un archivo PostScript es un archivo de texto sencillo que
comienza con el "mágico" PostSript%!PS.
413
[elvis@station elvis]$ head output.ps
%!PS-Adobe-3.0
%%BoundingBox: 18 18 558 720
%%Creator: Mozilla PostScript module (Galeon/2003022516)
%%DocumentData: Clean8Bit
%%DocumentPaperSizes: Letter
...
La siguiente línea de comandos puede utilizarse para ver el archivo con el intérprete Ghostscript.
...
GS>
El intérprete gs devuelve muchas líneas de tipos de fuente que carga, pero al final traduce la
imagen en una ventana X por separado. En la línea de comandos, el usuario es abandonado en un
intérprete de comandos interactivo Ghostscript GS> . Si el archivo PostScript contiene páginas
múltiples, un simple ENTER en el intérprete de comandos Ghostscript visualizará la próxima
página. Para aquellos que hablen PostScript, el intérprete puede utilizarse para entregar gráficas
de modo interactivo. Para aquellos que tengan menos conocimientos, un simple quit (o
CONTROL-D) hará salir al intérprete gs.
GS>quit
[elvis@station elvis]$
Por defecto, el intérprete gs traduce los archivos PostScript a una ventana dentro del entorno X.
Sin embargo, como lo ilusta la salida de los dispositivos disponibles del comando gs --help, el
comando ejecutable gs puede representar un gran número de formatos gráficos.
414
[elvis@station elvis]$ gs --help
GNU Ghostscript 7.05 (2002-04-22)
Copyright (C) 2002 artofcode LLC, Benicia, CA. All rights reserved.
Usage: gs [switches] [file1.ps file2.ps ...]
Most frequently used switches: (you can use # in place of =)
-dNOPAUSE no pause after page | -q `quiet', fewer messages
-g<width>x<height> page size in pixels | -r<res> pixels/inch resolution
-sDEVICE=<devname> select device | -dBATCH exit after last file
-sOutputFile=<file> select output file: - for stdout, |command for pipe,
embed %d or %ld for page #
Input formats: PostScript PostScriptLevel1 PostScriptLevel2 PDF
Available devices:
x11 x11alpha x11cmyk x11gray2 x11gray4 x11mono bmpmono bmpgray bmpsep1
bmpsep8 bmp16 bmp256 bmp16m bmp32b deskjet djet500 laserjet ljetplus
ljet2p ljet3 ljet3d ljet4 ljet4d lj5mono lj5gray cdeskjet cdjcolor
cdjmono cdj550 pj pjxl pjxl300 uniprint ijs omni bj10e bj200 bjc600
bjc800 faxg3 faxg32d faxg4 pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk
pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm
pksmraw tiffcrle tiffg3 tiffg32d tiffg4 tifflzw tiffpack tiff12nc
tiff24nc psmono psgray psrgb bit bitrgb bitcmyk pngmono pnggray png16
png256 png16m jpeg jpeggray pdfwrite pswrite epswrite pxlmono pxlcolor
bbox dmprt cdj880 ap3250 appledmp atx23 atx24 atx38 bmpa16 bmpa16m
bmpa256 bmpa32b bmpamono bmpasep1 bmpasep8 ccr cdj1600 cdj500 cdj670
cdj850 cdj890 cdj970 cfax cgm24 cgm8 cgmmono cljet5pr coslw2p coslwxl
cp50 declj250 dfaxlow dfaxhigh djet500c dl2100 dnj650c eps9high eps9mid
epson epsonc escp fs600 hl1250 hl7x0 ibmpro imagen inferno iwhi iwlo iwlq
jetp3852 la50 la70 la75 la75plus lbp8 lj250 lj3100sw lj4dith ln03 lp2563
lp8000 lq850 lxm5700m m8510 mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono
miff24 necp6 oce9050 oki182 okiibm paintjet photoex pjetxl plan9bm sgirgb
r4081 sj48 st800 stcolor sunhmono t4693d2 t4693d4 t4693d8 tek4696 xes
x11cmyk2 x11cmyk4 x11cmyk8 x11rg16x x11rg32x ljet4pjl lj4dithp dj505j
picty180 pr201 pr150 pr1000 pr1000_4 jj100 bj10v bj10vh mag16 mag256
mj700v2c mj500c mj6000c mj8000c fmpr fmlbp ml600 lbp310 lbp320 lips2p
bjc880j lips4 lips4v escpage lp2000 npdl md50Mono md50Eco md1xMono DJ630
DJ6xx DJ6xxP DJ8xx DJ9xx DJ9xxVIP AP21xx pcl3 md2k md5k stp lxm3200
lx5000 lex7000 lex5700 lex3200 lex2050 gdi epl5800 epl2050 epl2050p
alc8500 alc2000 cups cljet5 cljet5c nullpage
...
Mientras algunos de estos "dispositivos" de salida tales como jpeg y png256, se refieren a los
formatos estándar para archivos gráficos, muchos de los dispositivos se refieren a formatos
gráficos de impresoras sin PostScript o fax. La utilidad gs puede utilizarse en modo de lote para
convertir un gran número de archivos PostScript en otro formato o filtrar un documento para
impresión en una impresora sin PostScript.
Opción Efecto
-dNOPAUSE No hace pausa y espera un RETURN después de traducir cada página.
-dBATCH Sale automáticamente después de traducir la última página.
-q Opera "calmadamente" (no presenta un mensaje por cada página
traducida).
415
-sDEVICE=devname Utiliza el formato de salida devname
- Almacena la salida en el archivo filename. Si %d se incluye en el nombre
sOutputFile=filename de archivo, se remplazará con el número de página del documento multi-
página.
-rresolución Utiliza una resolución de resolución DPI (puntos por pulgada).
1. Escala dinámica: La imagen puede hacerse a escala para ajustar la anchura y altura de la
ventana o un porcentaje arbitrario.
2. Paginación: Al utilizar un panel lateral se puede navegar fácilmente un documento multi-
páginas y seleccionar páginas individuales para extraer dentro de un archivo PostScript
independiente o imprimir mediante el menú File como se ilustra a continuación.
En teoría, la aplicación Ghostview también sirve para ver archivos PDF. En la práctica, ggv
ocasionalmente tiene problemas interpretando documentos PDF. Pronto veremos una aplicación
más estable para visualizar los PDF. Algunos documentos PostScript multi-páginas pueden
también confundir a ggv. En casos en que ggv tiene problemas para traducir un documento
PostScript, el traductor de PostScript gs puede utilizarse directamente.
La aplicación xpdf es un simple visor de documentos PDF que sirve para ver, imprimir o convertir
documentos PDF en PostScript.
416
Las flechas en la esquina inferior izquierda permiten al documento navegar una página o 10
páginas al mismo tiempo. El botón del icono de impresora abre el siguiente diálogo, el cual permite
al usuario especificar una línea de comando lpr o un destino de archivo PostScript.
Otras alternativas para ver documentos PDF incluyen los comandos gs y ggv.
La utilidad gs puede utilizarse para convertir documentos PDF en cualquiera de los formatos de
salida listados anteriormente. Puesto que la sintaxis del comando gs puede ser tan engorrosa,
algunas utilidades frontales de línea de comando más sencillas están disponibles para convertir
PostScript en PDF: ps2pdf y amigos.
La sintaxis del comando ps2pdf es trivial, donde el primer argumento es la salida del nombre de
archivo PostScript (o un “-” para implicar la entrada estándar) y el segundo argumento es la salida
del nombre de archivo de salida PDF (o un “-” para implicar la salida estándar).
A manera de ejemplo rápido, elvis ahora utiliza el comando ps2pdf para convertir su archivo
output.ps en formato PDF, el cual es de calidad comparable, pero mucho más compacto.
1. Escala dinámica: La imagen puede hacerse a escala para ajustar la anchura y altura de la
ventana o un porcentaje arbitrario.
2. Paginación: Al utilizar un panel lateral se puede navegar fácilmente un documento multi-
páginas y seleccionar páginas individuales para extraer dentro de un archivo PostScript
independiente o imprimir mediante el menú File como se ilustra a continuación.
En teoría, la aplicación Ghostview también sirve para ver archivos PDF. En la práctica, ggv
ocasionalmente tiene problemas interpretando documentos PDF. Pronto veremos una aplicación
más estable para visualizar los PDF. Algunos documentos PostScript multi-páginas pueden
también confundir a ggv. En casos en que ggv tiene problemas para traducir un documento
PostScript, el traductor de PostScript gs puede utilizarse directamente.
417
Ver documentos PDF con xpdf
La aplicación xpdf es un simple visor de documentos PDF que sirve para ver, imprimir o convertir
documentos PDF en PostScript.
Las flechas en la esquina inferior izquierda permiten al documento navegar una página o 10
páginas al mismo tiempo. El botón del icono de impresora abre el siguiente diálogo, el cual permite
al usuario especificar una línea de comando lpr o un destino de archivo PostScript.
Otras alternativas para ver documentos PDF incluyen los comandos gs y ggv.
La utilidad gs puede utilizarse para convertir documentos PDF en cualquiera de los formatos de
salida listados anteriormente. Puesto que la sintaxis del comando gs puede ser tan engorrosa,
algunas utilidades frontales de línea de comando más sencillas están disponibles para convertir
PostScript en PDF: ps2pdf y amigos.
La sintaxis del comando ps2pdf es trivial, donde el primer argumento es la salida del nombre de
archivo PostScript (o un “-” para implicar la entrada estándar) y el segundo argumento es la salida
del nombre de archivo de salida PDF (o un “-” para implicar la salida estándar).
A manera de ejemplo rápido, elvis ahora utiliza el comando ps2pdf para convertir su archivo
output.ps en formato PDF, el cual es de calidad comparable, pero mucho más compacto.
418
Opción Efecto
-o filename Generar salida del archivo filename.
-2, Formatear texto en 2 (o num) columnas.
--columns=num
-a páginas Solamente imprime páginas páginas. páginas pueden ser de la forma
comienzo-fin, la palabra impar o par.
-b encabezado Utiliza el encabezado de texto como un encabezado de página. Un formato
elaborado es provisto para especificar nombre de archivo, número de página,
etc.
-d impresora Envia salida a la cola de impresiónimpresora.
-E [lang] Representa el texto con sintaxis resaltada apropiada para el lenguaje de
programación lang. Utiliza --help-pretty-print para listar los idiomas
soportados.
-G Representa páginas con un encabezado elegante.
-r Rota la página 90 grados.
-W lang Genera salida en idioma lang, que puede ser de PostScript, html,
superposición o rtf.
Existen muchas más opciones. Para mayor información, consulte la página de manual enscript(1).
A manera de ejemplo, la siguiente línea de comandos traduciría el archivo de encabezado C
malloc.h como PostScript con 2 columnas por página, rotado y representado con un encabezado
elegante y una sintaxis resaltada.
El comando mpage puede utilizarse para extraer páginas desde la mitad de un documento
PostScript multi-páginas o reformatear el documento a imprimir con múltiples páginas por hoja.
El mpage acepta PostScript o texto como entrada. El texto se traduciría en PostScript antes de
administrar. Los argumentos se consideran archivos de entrada con la salida dirigida a la salida
estándar.
Opción Efecto
-o filename Generar salida del archivo filename.
-1, -2, -4, -8 Imprimir un número especificado de páginas por hoja impresa (4 por
defecto).
-j primero[-último] Sólo imprime un rango especificado de páginas incluyendo sólo los
[%intervalo] intervalo de páginas, si se especifican.
-l Cambia el modo de formato horizontal a vertical.
-o Cambia a imprimir borde alrededor de cada página (por defecto está
activo).
-P [impresora] Envía salida PostScript a la cola de impresión impresora.
-G Representa páginas con un encabezado elegante.
419
-r Rota la página 90 grados.
-G Representa páginas con un encabezado elegante.
-W lang Genera salida en idioma lang, que puede ser de PostScript, html,
superposición o rtf.
Ejercicios en línea Lab Exercise Objetivo: Practicar la salida para impresión. Tiempo estimado:
20 minutos.
Especificaciones
420
2. Utilice el comando mpage para extraer las páginas 8 y 9 del archivo getconf.ps creado
anteriormente, almacénelas en un nuevo documento llamado getconf89.ps.
(Por defecto el comando mpage imprimirá 4 hojas por páginas de salida, confundiendo el
conteo de páginas. Incluya la opción apropiada para que sólo una página de entrada sea
impresa por página de salida).
1. Un documento de múltiples páginas PostScript getconf.ps que contiene el texto del archivo
/usr/share/doc/bash-*/loadables/getconf.c, impreso en 2 páginas por página de salida.
2. Un documento PostScript de dos páginas getconf89.ps que contiene las páginas 8 y 9
extraídas del documento getconf.ps.
3. El documento PDFgetconf89.pdf, el cual es el contenido del documento PostScript
getconf89.ps convertido en formato PDF.
Un script titulado ~/bin/ps2jpeg que cuando se invoca con un documento PostScript como
su único argumento, convertirá el documento en una imagen JPEG llamada output.jpg.
421
Sinopsis del correo electrónico
Conceptos clave
Discussion
Es discutible que el servicio más popular ofrecido por Internet es el correo electrónico. El correo
electrónico es un concepto sencillo: Alicia escribe un archivo de texto y especifica enviarlo a Bob.
Cuando Bob revisa su correo, el archivo de texto estará esperando por él, etiquetado como enviado
por Alice. Sin embargo, en la práctica, el sistema de envío de correo electrónico debe ofrecer
soluciones a algunos problemas bastante complicados.
El software que Alice y Bob utilizan debe resolver los siguientes problemas.
En algunos casos, el recipiente de correo utiliza una máquina que no tiene una conexión
permanente de Internet o está detrás de un cortafuegos, lo que luego complicará las cosas. En
esta lección, trataremos varios procedimientos que ofrecen soluciones a estos problemas.
La solución fácil
La solución más sencilla es la apropiada para los usuarios de computadores con conexiones
deinternet bien conocidas y permanentes. En el momento en que muchos protocolos definían cómo
enviar correo electrónico, ésta fue la solución estándar. Dicha solución implica dos aplicaciones
separadas cuyos roles se identifican por TLA (acrónimos de tres letras). La primera aplicación se
422
conoce como MTA Agente de Transporte de Correo y la segunda se conoce como MUA, o Agente
de correo de usuario.
El MTA suele operar en el segundo plano, realizando el trabajo de una oficina postal. El MTA
recibe correo electrónico para ser envíado desde programas en la máquina local, determina desde
la dirección del destinatario la máquina apropiada que debe contactar e intenta conectarse a un
MTA complementario ejecutando en la máquina de destinatarios, quienes deben estar escuchando
el puerto 25. Si el remitente de MTA no puede contactar el receptor de MTA, el correo se almacena
temporalmente en la máquina del remitente y el MTA de remitente intenta de nuevo más tarde.
El MTA también se enlaza al puerto local 25, donde recibe conexiones de otros MTA. Cuando éste
recibe correo desde un MTA remoto destinado a un usuario en una máquina local, recibe el correo
y lo almacena en un directorio de almacenamiento temporal conocido como el buzón de entrada
del usuario. En Linux (y Unix), el buzón predeterminado del usuario es /var/spool/mail/username
para que el correo en espera del usuario elvis se instale en el archivo /var/spool/mail/elvis.
El MTA por defecto de Red Hat Enterprise Linux es un demonio llamado sendmail.
Red Hat Enterprise Linux se distribuye con una amplia selección de MUAs, varios de los cuales se
describirán en ésta y en la siguiente lección.
423
Servidores de buzón
Aunque la solución anterior es simple, requiere que primero, todos los usuarios estén recibiendo
correo electrónico en una máquina conectada constantemente a Internet y segundo, que la
máquina tenga un nombre de equipo bien conocido y accesible a otros. Muchos usuarios que por
ejemplo, utilizan una conexión de "marcado" o de "alta velocidad" desde un ISP (Proveedor de
Servicios Internet) o que estén utilizando máquinas detrás de un cortafuegos de una institución, no
están en esta situación. Otra solución se ha desarrollado para servir a la gente en este caso: los
servidores de buzón.
En el diagrama anterior, asumimos que elvis está utilizando una conexión de Internet de "alta
velocidad" para la cual se ha suscrito a la compañía "ISP.Net". Cuando se conecta al Internet, su
máquina ISP le emite a su máquina una dirección IP, pero elvis no puede predecir la dirección IP
que recibirá. El nombre del equipo, al cual se le asignó el ISP a la dirección IP, es probablemente
poco atractivo por ejemplo, dhcp-191-93.isx.isp.net, por lo tanto si elvis garantizara la recepción de
la misma dirección IP cada vez, no desearía publicar su nombre de equipo como su dirección de
correo electrónico.
En su lugar, elvis aprovecha una "cuenta de correo electrónico" que le ofrece su ISP. Es muy
probable que su cuenta exista en una máquina Linux o Unix del ISP conectada permanentemente a
Internet y se le asigne un nombre de host como por ejemplo pop.isp.net. El ISP ha clasificado todo
el correo electrónico destinado a direcciones de forma [email protected] para ser enviado al MTA de
esta máquina. Cuando el MTA ejecutándose en pop.isp.net recibe correo para elvis, lo almacena
en un directorio de almacenamiento temporal dedicado a elvis (muy probable en el archivo
sendmail./var/spool/mail/elvis) y el correo electrónico se considera como entregado.
Dado que la máquina de ISP pop.isp.net tiene una conexión de Internet permanente y bien
conocida, es mejor candidata para recibir correo electrónico que la máquina de elvis en casa.
Cuando elvis está en casa, aún necesita tener acceso a su correo electrónico que está en su buzón
de entrada en pop.isp.net. Este acceso suele estar provisto en forma de un servidor POP
(Protocolo de servidor de correo) o servidor de IMAP (Protocolo de Servicio de Correo por Internet).
Servidores POP
Los servidores POP realizan un servicio muy sencillo. Permiten a los usuarios acceder al directorio
de almacenamiento temporal de un sólo usuario y transfieren su contenido a su MUA local. Los
424
servidores POP suelen enlazarse al puerto 110 y requieren que cualquier cliente se autentique
mediante un par de nombres de usuario-contraseña. La mayoría de los MUAs modernos actúan
como clientes POP y pueden configurarse para recuperar correo de un servidor especificado.
Si un servidor de buzón ejecuta el servicio POP, suele implicar que el servidor de buzón no intenta
almacenar de modo permanente, sino temporalmente hasta que el usuario "lo baje "a su máquina
local.
Servidores IMAP
Los servidores IMAP suelen ofrecer a los clientes administración de buzones de manera más
sofisticada. Los usuarios IMAP pueden mantener varias carpetas en el servidor de buzón no sólo
su buzón de entrada individual. En general, un servidor IMAP implica que un correo electrónico del
usuario sea almacenado de forma permanente en el servidor de buzón y los usuarios
ocasionalmente se conecten con un MUA desde una máquina remota para "navegar" su correo.
Los servidores IMAP suelen encontrarse en entornos institucionales y corporativos. Los demonios
IMAP se enlazan al puerto 143.
Envío de correo
Puesto que la máquina de elvis mantiene una conexión de Internet casi continua, elvis aún desea
utilizar su MUA local para enviar correo. Si el MUA local no puede conectarse temporalmente a la
máquina del destinatario, el MUA almacenará el correo temporalmente de modo local y tratará de
enviarlo más tarde.
Por defecto, Red Hat Enterprise Linux está configurado de modo apropiado para esta situación. El
MTA local se inicia, pero no aceptará conexiones a través del puerto 25 (excepto desde la dirección
de bucle local, 127.0.0.1). Sirve simplemente para entregar correo electrónico saliente. Se asume
que los usuarios tienen acceso a su correo electrónico desde un servidor POP o IMAP.
La configuración predeterminada puede cambiarse, pero la configuración necesaria va más allá del
alcance de este curso.
Para máquinas que sólo tienen conexiones a Internet transitorias, el intentar entregar correo
electrónico mediante el MTA local puede no ser apropiado. En su lugar, los usuarios de conexiones
de "marcado" y similares suelen utilizar lo que se conoce como un SMTP (Protocolo sencillo de
transferencia de correo) o servidor de correo saliente. Muchos ISP e instituciones ofrecen
servidores SMTP salientes, a menudo con nombres como smtp.isp.net.
425
El MTA en el servidor SMTP desea aceptar correo de máquinas "locales", a pesar de que no es el
destinatario final para el correo electrónico. En su lugar, el servidor SMTP transmite el correo y lo
reenvía a su destino. Si se presenta algún problema, el almacenamiento temporal y el reenvío de
correo pendiente es ahora responsabilidad del servidor SMTP.
Muchos MUAs permiten a los usuarios especificar un equipo remoto para que actúe como el
servidor SMTP del usuario (contrario a reenviar correo al MTA local para envío). [1]
Entrega local
Todos los casos anteriores asumen que el usuario está enviando correo electrónico desde su
máquina a un destinatario en una máquina remota. Linux (y Unix) también permite a los usuarios
en una máquina local enviar correo electrónico entre sí, donde el correo electrónico se dirige
únicamente al nombre de usuario tal como blondie.
Para entrega local no se requiere ninguno de los servidores locales POP o SMTP porque el correo
electrónico se entrega al instante por el MTA local.
El MUA mail
Quizás el MUA más sencillo es un comando llamado simplemente mail. El comando mail data de
los primeros días de Unix y por lo tanto depende altamente del MTA local. El comando mail no
puede ser configurado para acceder al correo desde un servidor POP o IMAP, ni puede ser
configurado para utilizar un servidor SMTP para correo saliente. En su lugar, puede esperar correo
que sea enviado al directorio de almacenamiento temporal y pasa al MTA de correo local para
envío.
No obstante, en situaciones tales como envío de correo a usuarios locales, el comando mail puede
ser bastante eficaz.
426
El comando mail puede utilizarse para enviar correo a destinatarios especificados como
argumentos en la opción de la línea de comandos. El cuerpo del mensaje se lee desde la entrada
estándar (la cual puede leerse desde una tubería, un archivo redirigido o desde un teclado
directamente, en donde CONTROL-D ("EOF") se utiliza para indicar el fin del mensaje).
Las opciones de línea de comandos en el cuadro siguiente pueden utilizarse para especificar una
línea de asunto, destinatario a, "Cc:", etc.
Opción Efecto
-v Modo verboso. Imprime la comunicación entre el comando mail y el MTA local (o
remoto).
-s Especifica una línea de asunto.
asunto
-c addrs Envía copia a las direcciones especificadas.
-b addrs Envía copias ciegas a direcciones especificadas.
A manera de ejemplo, a continuación, elvis envía por correo el contenido del archivo lyrics.txt a
blondie.
En el siguiente ejemplo, blondie está utilizando el comando mail sin argumentos para ver el correo
en su buzón y luego borrar el mensaje y salir.
& d
& q
427
Ejemplos: Envío de correo
Una forma fácil y rápida de enviar archivo de texto a otro usuario es con mail
Mediante un simple comando de correo con la opción verbosa, un usuario puede observar el
proceso por el que pasa sendmail para entregar un mensaje.
Ejercicios en línea Lab Exercise Objetivo: Enviar correo electrónico a usuarios locales.
Estimated Time: 10 mins.
Especificaciones
428
1. Utilice el comando mail para enviar por correo el contenido del archivo /proc/cpuinfo a sus
cuentas primaria y alterna (i.e, los usuarios nombredeusuario_a y nombredeusuario_b,
donde nombre de usuario es el nombre de su cuenta primaria.
2. Cree el archivo ~/you_have_mail que contiene una lista ordenada de todos los usuarios en
su sistema local que actualmente tienen correo en sus "buzones de entrada" (i.e. su
directorio de almacenamiento temporal entregado pero no leído aún). Debe incluir usuarios
de "sistema" en su lista y listar un usuario por línea.
1. Sus cuentas alternas primera y segunda tienen el contenido del archivo /proc/cpuinfo en su
depósito de correo entregado.
2. El archivo ~/you_have_mail debería contener una lista ordenada de como los usuarios
tienen correo en espera en su depósito de correo, (obviamente, sus nombres de cuentas
alternas primera y segunda deben incluirse en esta lista).
429
El MUA Evolution
Conceptos clave
Discussion
Evolution
Quizás el MUA más sofisticado que se distribuye con Red Hat Enterprise Linux es evolution. El
agente de usuario de correo es apenas un componente del administrador de la información
personal de evolution. En esta sección, presentamos algunas de las características clave de la
aplicación evolution e identificamos cómo configurar evolution para recibir correo electrónico
desde varias fuentes y cómo enviar correo mediante el servidor local MTA o el servidor remoto
SMTP.
De hecho, Evolution es mucho más que un MUA. En la toma de pantalla siguiente verá que
también tiene herramientas para administrar contactos, calendario de eventos y listas de tareas. Lo
invitamos a experimentar con estos elementos cuando el tiempo se lo permita, pero la lección se
enfocará en el uso de evolution para envío y recepción de correo.
Desde la pantalla principal, el correo se puede clasificar en una jerarquía de carpetas navegables
mediante el recuadro en la parte superior izquierda. En la parte superior derecha del recuadro, se
presenta un resumen de mensajes almacenados en la carpeta actual seleccionada. En el recuadro
de la parte inferior derecha se visualiza el contenido del actual mensaje.
Haciendo "click derecho" en un mensaje, un menú emergente ofrece una variedad de acciones,
tales como almacenar el mensaje como archivo de texto, responder a un mensaje o reenviar el
mensaje, "marcando" el mensaje con una bandera particular, "etiquetando" el mensaje en un color
determinado o identificando el mensaje como correo basura.
Un mensaje se puede archivar en otra carpeta con sólo arrastrar el mensaje al sitio de la carpeta
deseada en el panel a mano izquierda.
430
Por último, los filtros se pueden crear al tratar correos electrónicos con características similares al
actual mensaje.
Como es texto escrito, las palabras no identificadas por el corrector ortográfico son subrayadas y
con un click derecho, se sugieren remplazos que pueden buscarse en el diccionario o palabras que
pueden agregarse al diccionario personal del usuario.
Al seleccionar el menú Security, los usuarios pueden elegir entre firmar o encriptar su mensaje
mediante un protocolo de clave pública encriptada.
Como se ve a continuación, los filtros se componen de una selección de criterios coincidentes que
serán aplicados al correo electrónico recibido. Si un mensaje coincide con los criterios entonces se
pueden poner en práctica una norma o un grupo de normas.
Cuando coincide, el mensaje puede estar sujeto a alguna combinación de los siguientes destinos.
431
• El mensaje puede entubarse a una shell de comando arbitraria.
Evolution permite a los usuarios administrar múltiples cuentas, donde una cuenta representa un
origen particular de correo electrónico, un destino particular para correo electrónico, una identidad
particular de un remitente entre otras opciones.
Las cuentas se pueden crear, borrar, habilitar, inhabilitar o modificar mediante el siguiente diálogo,
el cual se obtiene seleccionando Herramientas: Configuración... y eligiendo el "Panel de cuentas de
correo".
Evolution, permite recuperar correspondencia desde varias fuentes como se puede apreciar en el
siguiente diálogo.
Las primeras dos selecciones especifican que el correo se debería recuperar desde los servidores
POP o IMAP. Para cada uno, el diálogo permite especificar el nombre de servidor, el nombre de
cuenta y la contraseña. Si el servidor de POP o IMAP soporta codificación, el encapsulado SSL
puede especificarse. También se ofrecen otros esquemas de autenticación (diferentes a un par de
nombre de usuario-contraseña), si el servidor los soporta.
El resto de las opciones permiten a evolution sacar correo directamente del depósito de correo
MTA o compartir carpetas con otros MTA como por ejemplo, mutt, pine y elm.
Si se debe utilizar un host SMTP, debe especificarse el nombre del host. Además se pueden
establecer soporte para conexiones encriptadas o autenticación de usuario si la máquina SMTP es
compatible o lo requiere.
La otra alternativa es hacer que evolution entregue correo simplemente pasándolo al MTA local
("enviar correo"), en cuyo caso no hay ninguna otra configuración.
432
Aplicaciones de diagnósticos de red
Conceptos clave
Discussion
Dirección IP
Linux (y Unix) representa los dispositivos de red conectados a una máquina (tales como una tarjeta
Ethernet, una tarjeta Token-Ring, un módem utilizado para conexiones de marcado, etc...) como
una interfaz de red. Antes de que una interfaz pueda utilizarse para enviar o recibir tráfico, debe
configurarse con una dirección IP que sirve como la identidad de la interfaz.
Portal predeterminado
Para comunicarse con las máquinas fuera de la subred local, su máquina debe conocer la
identidad de un router cercano. El router utilizado para encaminar paquetes fuera de su subred
local se conoce como un portal predeterminado.
Nameserver
Otras máquinas en internet a su vez se identifican por una dirección IP. La gente suele pensar en
términos de nombres, por lo tanto el protocolo se ha desarrollado para asignar nombres a las
direcciones IP. El protocolo se llama Servicio de Nombres de Dominio o más conocido como DNS.
433
El protocolo DNS requiere que cada máquina tenga disponible uno o más servidores DNS
(comúnmente llamados servidores de nombre), los cuales pueden servir tanto de base de datos
para asignar un nombre a direcciones locales IP como también de punto de partida para determinar
direcciones IP para nombres de dominio de los cuales el servidor no tiene conocimento directo.
En una lección anterior presentamos el comando hostname -i, el cual muestra la dirección IP en
su equipo local. En realidad una "máquina" no tiene una dirección IP, las interfaces de red sí. Esta
lección tratará el tema de direcciones IP de interfaces de red en mayor detalle.
En Linux (y Unix), cada dispositivo de red se representa como una interfaz de red, (por una vez,
¡encontramos algo que no es un archivo!). Linux nombra interfaces de acuerdo con el tipo de
dispositivo que representa. El siguiente cuadro lista algunos de los nombres más utilizados en
Linux.
Interfaz Dispositivo
ethn Tarjeta Ethernet
trn Tarjeta de Token-Ring
fddin Tarjeta de fibra óptica
pppn Conexión de marcado a través de módem
lo Dispositivo de bucle local
En cada caso, n se remplaza por un número entero para cada instancia de un dispositivo
determinado conectado a una máquina.
El comando ifconfig muestra la configuración de interfaces de red activas. Puesto que el comando
suele ser utilizado por root para configurar interfaces, éste vive dentro del directorio /sbin, el cual
está fuera de la RUTA predeterminada para los usuarios estándar. No obstante, los usuarios
estándar pueden usar el comando para ver información de configuración de interfaz, utilizando una
referencia absoluta como en el ejemplo a continuación.
434
A la interfaz eth0 se le asigna una dirección IP de 192.168.0.254.
Como se mencionó al comienzo de la lección, para la comunicación con equipos en sus subredes
locales se utilizan procedimientos diferentes a la comunicación con hosts en una subnet separada.
El kernel de Linux, al igual que otras kernels, define las máquinas que deberían considerarse
locales y la gateway que debería usarse para ayudar a comunicarse con aquellas que no lo son.
Este cuadro se llama cuadro de enrutamiento.
Si usted es un usuario estándar, el comando route se puede utilizar para ver el cuadro de
enrutamiento del sistema. Si es un usuario root, el comando puede también utilizarse para
manipular el cuadro. Al igual que el comando ifconfig, el comando route vive en el directorio /sbin,
por lo tanto los usuarios estándar deben invocarlo mediante una referencia absoluta.
Un cuadro de ruta estándar visualiza dos tipos de entrada. El primer tipo define qué subredes se
deben considerar como locales. En general, debería haber una línea que especifique una subred
para cada interfaz activa. En la salida anterior, la primera línea define la subnet asociada con la
interfaz de Ethernet (con una dirección IP de 192.168.0.51) y la segunda línea define la subred
asociada con la interfaz de bucle local (con una dirección IP de 127.0.0.1).
El segundo tipo de entrada que sirve para definir gateways es el más importante para nuestra
discusión. Dichas entradas de gateway se pueden distinguir porque el host está definido en la
segunda columna ("Gateway") y la cuarta columna ("Banderas") contiene una "G". Cada cuadro de
ruta debe contener una entrada para la gateway "por defecto" y la segunda columna debe contener
el nombre del host del gateway.
La misma información se puede ver mediante la dirección IP en lugar de nombres del host
utilizando /sbin/route -n.
435
Aquí, blondie determina que su máquina está utilizando el host 192.168.0.254 como su
gateway predeterminado.
La bandera "G" indica que esta línea se utiliza para definir una gateway, no una subred local.
El Servicio de Nombres de Dominio permite a los usuarios referirse a los computadores de la red
mediante nombres de host en lugar de direcciones IP. A diferencia de los otros dos aspectos de
configuración de red, un servidor de nombre es hasta cierto punto opcional. Con el fin de
comunicarse con otras máquinas su equipo debe tener una dirección IP. Si desea comunicarse con
máquinas fuera de la subred, usted debe tener una gateway por defecto. Sin embargo, si los
usuarios quieren referirse a cada máquina por dirección IP en lugar de nombre de máquina, su
equipo puede comunicarse mediante el protocolo IP sin consultar el servidor de nombres.
No obstante, en la práctica los servidores de nombres parecen ser más necesarios (se le facilita
más memorizar academy.redhat.com o 66.187.232.51?). Convertir un nombre de host en una
dirección IP suele conocerse como resolver una dirección y la biblioteca que ejecuta el servicio de
nombre se llama la biblioteca resolv. Cuando la biblioteca intenta resolver una dirección suele
haber dos recursos disponibles.
El primer recurso es un archivo de texto sencillo llamado archivo /etc/hosts. Aunque sólo root
puede editar el archivo cualquier usuario puede observarlo.
El formato del archivo es sencillo. El primer símbolo en la línea debería ser una dirección IP y los
símbolos subsiguientes son nombres de hosts que deberían apuntar a la dirección IP. El caracter
estándar de comentario de Unix (“#”) también es compatible.
Si el equipo sólo se está comunicando con pocas máquinas o si un administrador desea crear un
atajo de nombres de host (tal como “s”) o si deseara anular el servidor de nombre local, las
entradas pueden agregarse al archivo /etc/hosts mediante un editor de texto sencillo.
Claro está que esta técnica no escala bien. Usted no puede esperar que el archivo /etc/hosts le
responda a todo.
Cuando el /etc/hosts local no puede dar respuesta, la biblioteca resolv consulta un servidor de
nombres. Para determinar qué máquina consultar que esté ejecutando un servidor de nombres,
examina el archivo de configuración de la biblioteca de resolv, /etc/resolv.conf.
436
[blondie@station blondie]$ cat /etc/resolv.conf
; generated by /sbin/dhclient-script
search example.com
nameserver 192.168.0.254
nameserver 207.175.42.153
El archivo de configuración /etc/resolv.conf utiliza líneas que comienzan por la palabra clave
servidor de nombres para especificar las direcciones IP de máquinas ejecutando servidores de
nombre. Si se especifican varios servidores de nombres, se utilizará el primero por defecto. Si no
está disponible se utilizará el segundo y así sucesivamente. Por consiguiente, el primer servidor de
nombres listado suele llamarse servidor de nombres primario, el segundo servidor listado servidor
de nombres secundario y así sucesivamente.
Observe que el servidor de nombres no necesita estar cerca de la máquina. Cualquier equipo que
esté ejecutando el servidor de nombres y le permita solicitarlo, puede usarse como servidor de
nombres. En la práctica, el uso de un servidor de nombres local genera un mayor rendimiento.
En las secciones anteriores, hemos esbozado las técnicas más directas para determinar su
configuración de red IP local de la máquina. En esta sección, presentaremos las utilidades de
diagnóstico que sirven para asegurar que las configuraciones están funcionando correctamente
con su entorno de red local.
El comando ping sirve para confirmar la conectividad IP entre dos equipos. El primer argumento
para ping puede ser el nombre del equipo o la dirección IP de la máquina que usted desearía
contactar.
El comando ping debería presentar una línea por segundo, incluyendo el número de secuencia y la
información de temporización sobre la demora de ida y vuelta, la cual reporta el tiempo necesario
para recibir una respuesta de la máquina remota. El comando ping continuará ejecutándose hasta
cancelarse con la secuencia de control CONTROL-C.
437
Si no hay respuesta para el comando ping, usted no podrá esperar que se presente ninguna
comunicación de red de alto nivel. El culpable suele ser un cable Ethernet que se ha desconectado
físicamente de la máquina o de la pared.
Las inconsistencias en la tasa en la que las líneas se presentan o la discontinuidad en los números
de secuencia son generalmente indicativos de una red congestionada o de una conexión ruidosa y
se puede esperar un bajo rendimiento de red de protocolos de alto nivel.
Cuando se conecte a una máquina fuera de su subred, su paquete pasa de router a router a
medida que atraviesa varias subredes hasta que finalmente se envía a la subred que contiene la
máquina destino. La ruta del paquete, cuando pasa de router a router puede trazarse con el
comando /usr/sbin/traceroute.
El comando traceroute suele llamarse con un argumento, el nombre del equipo o la dirección IP de
la máquina destino.
Usted hallará con frecuencia que los paquetes toman rutas sorpresivas para ir de un lugar a otro. El
número de routers que su paquete pasa suele conocerse como el número de saltos que ha hecho
el paquete. El paquete anterior hizo 17 saltos para alcanzar su destino.
Si su paquete no puede completar el primer salto, es probable que su gateway por defecto de su
máquina no haya sido determinada correctamente. Si su traceroute termina entre la primera pareja
o salta (sin alcanzar el destino final), el problema es un router local mal configurado y su
administrador de red local probablemente ayude a resolver el problema. Si el comando traceroute
se agota a más de cuatro o cinco saltos, es probable que el problema esté fuera de control de su
administrador de red local.
438
El comando host se puede utilizar para realizar directamente solicitudes DNS. Con un argumento,
el comando host sólo reportará la resolución DNS solicitada.
Trying "academy.redhat.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53870
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 0
;; QUESTION SECTION:
;academy.redhat.com. IN ANY
;; ANSWER SECTION:
academy.redhat.com. 284 IN A 66.187.232.51
;; AUTHORITY SECTION:
redhat.com. 584 IN NS ns1.redhat.com.
redhat.com. 584 IN NS ns2.redhat.com.
redhat.com. 584 IN NS ns3.redhat.com.
En este ejemplo, el servidor de nombres que respondió tiene una dirección IP de 192.168.0.254.
Ejemplos
La usuaria madonna está teniendo problemas para que su navegador de red mozilla se conecte al
sitio www.yahoo.com y cree que la máquina local podría estar mal configurada. Procede a
examinar sus configuraciones de red local y confirma que parecen funcionales.
Siguiendo el consejo de iniciar con lo básico, madonna primero se asegura que la máquina tenga
una dirección IP, examinando su configuración de interfaz de red local.
439
[madonna@staton madonna]# /sbin/ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:8B:0C:B1:D5
inet addr:109.125.90.86 Bcast:109.125.90.255
Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:513364 errors:0 dropped:0 overruns:0 frame:0
TX packets:319118 errors:0 dropped:0 overruns:0 carrier:0
collisions:5068 txqueuelen:100
RX bytes:78770024 (75.1 Mb) TX bytes:356094835 (339.5 Mb)
Interrupt:11
440
Puesto que ella todavía no ha llamado el host externo de su subred local, intenta llamar a un
servidor de nombres terciario.
Los resultados del comando ping son un poco problemáticos, porque la mayoría de sus paquetes
se han quitado. En su lugar ella intenta determinar el camino recorrido por los paquetes a la
máquina.
Puesto que traceroute retornó dicha solicitud de salida, madonna asume que cualquier problema
observado con el comando ping anterior debió haber sido transitorio.
Por último, ella confirma que su servidor de nombres es operacional al realizar unas pocas
solicitudes de DNS con el comando host.
Convencida de que todo parece estar bien, trata de nuevo el navegador de red mozilla y tiene
éxito. Sea cualquiera el problema que estaba teniendo debe haberse relacionado con la congestión
de red transitoria observada con el comando ping.
441
Ejercicios en línea Lab Exercise Objetivo: Determinar la configuración de red local. Tiempo
estimado: 15 minutos.
Especificaciones
Crear los siguientes archivos, cada uno de los cuales debería contener su dirección IP como un
"quad punteado".
Archivo Contenido
~/net_ipaddr La dirección IP asignada a la interfaz eth0.
~/net_gw La dirección IP preseterminada de su gateway.
~/net_ns La dirección IP del servidor de nombres primario.
Los tres archivos presentados arriba, cada uno de los cuales contiene la dirección IP especificada
como su única palabra.
442
Terminal de red y clientes FTP
Conceptos clave
• El cliente HTTP de terminal Elinks, invocado como el comando links se puede utilizar para
navegar páginas web desde un entorno gráfico.
• La aplicación curl es una aplicación de protocolo múltiple no interactivo (incluyendo HTTP,
HTTPS y FTP) que sirve para transferir archivos en modo de lote.
• La aplicación wget es una aplicación de protocolo múltiple no interactiva (incluyendo
HTTP, HTTPS y FTP) que sirve para transferir de modo recursivo páginas web, buscando
en todas las páginas las referencias de página web.
Discussion
Los usuarios probablemente están familizados con las aplicaciones gráficas tales como mozilla
para navegar la red o nautilus para tener acceso a servidores FTP. Aparte de estas aplicaciones,
Linux también ofrece una amplia colección de clientes basados en la línea de comandos. ¿Por qué
alguien estaría tentado a utilizar clientes basados en líneas de comandos en lugar de apuntar y
hacer click en las aplicaciones?
• La razón obvia: si no está ejecutando en un entorno gráfico X, estas son las únicas
utilidades disponibles.
• Las utilidades se pueden escribir en scripts. Si tiene que extraer información de forma
repetitiva del mismo sitio, debería considerar un script para que haga el trabajo repetitivo
por usted.
• Las utilidades de la línea de comandos requieren menos recursos. Si está tratando de
descargar un archivo largo en otras máquinas ocupadas, un proceso curl es mucho más
atractivo que un proceso mozilla, porque el primero consume 4 megabytes mientras que el
segundo consume 40 megabytes de memoria.
• La simplicidad tiende a motivar la estabilidad. Cuando se descargan archivos grandes,
como por ejemplo, imágenes ISO de 700 megabytes, muchas de las aplicaciones pueden
volverse inestables, (la lista de culpables incluye a Internet Explorer). Los clientes de línea
de comandos como curl tienden a generar resultados más estables.
El texto Elinks de cliente HTTP (navegador de red) está diseñado para traducir páginas web en una
terminal, emulando la presentación de un navegador de red gráfico. En cuanto sea posible, los
cuadros y formas se presentan en escala. Observe que en la siguiente visualización de la página
de red asociada con Red Hat Network, los marcos y cuadros están traducidos correctamente.
Inicio de Elinks
Los Elinks se inician como el comando links especificando una URL para cargar como un
argumento. Observe el siguiente ejemplo.
443
Figure 1. El navegador de texto Elinks
Cuando utilice links, la pantalla está activa y los enlaces pueden navegarse mediante teclas de
flechas o el ratón. Al utilizar la tecla ESC, se crea un menú que permite al usuario acceder a los
diálogos de favoritos, historial y personalización.
Aunque la opción -dump sirve para entregar una página en una salida estándar y la opción
-source hará lo mismo al contenido "Crudo" de la URL (a menudo botando HTML), el soporte para
interacciones de guiones es muy poco sofisticado comparado con otras utilidades tales como curl.
La potencia del navegador links es su capacidad para proporcionar una grata experiencia de
navegación de red en un entorno de texto.
Si se establece la variable del entorno HTTP_PROXY, los Elinks utilizarán el servidor proxy
especificado, donde el servidor proxy (al igual que el navegador Elinks) puede especificarse
mediante la siguiente sintaxis.
http://servername:puerto
En contraste, el comando links, el cliente de red de la línea de comando curl no se esfuerza por
verter o navegar interactivamente las páginas web. En cambio, el desarrollo de curl se ha
enfocado en una amplia colección de opciones que se adaptan para la entrega automática de
archivos publicados mediante una red o un servidor ftp. Este texto tendría dificultades describiendo
curl, pero algo más efectivo y suscinto es referirse a la página del manual curl(1):
444
curl es un cliente que sirve para obtener documentos/archivos o enviar documentos a un
servidor, utilizando cualquiera de los protocolos compatibles (HTTP, HTTPS, FTP, GOPHER,
DICT, TELNET, LDAP o ARCHIVO). El comando está diseñado para funcionar sin
interacción de usuario u otra clase de interacción.
curl ofrece una carga de trucos útiles como soporte proxy, autenti-
cación de usuario, carga ftp, texto HTTP post, SSL conexiones (https:), cookies,
reanudar transferencia de archivo y más.
Inicio curl
Cuando se llame con una URL como su argumento, el comando curl recupera y descarga su
contenido en la salida estándar. Además, alguna información de temporización se escribe en el
error estándar, el cual se desecha en el siguiente ejemplo.
<html>
<head>
<title>Red Hat -- Linux, Embedded Linux and Open Source Solutions</title>
<meta name="MSSmartTagsPreventParsing" content="TRUE">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
El siguiente cuadro lista algunas de las opciones que se pueden utilizar para modificar la conducta
de curl. Consulte la página de manual curl(1) para obtener la lista completa.
Opción Efecto
-b, --cookie filename Proporciona valores de cookie desde el archivo especificado.
-c, --cookie-jar filename Almacena las cookies recuperadas en el archivo especificado.
-C, --continue-at posición Reanuda la transferencia de un archivo grande en una
posición especificada. Si se da como “-”, curl tratará de
encontrar automáticamente la posición apropiada.
-d data Proporciona datos como si los enviara a solicitud POST.
-i Incluye encabezados HTTP en la salida.
-L, --location Sigue redirecciones a una nueva ubicación.
-m, --max-time segundos Mata la conexión después de que el número especificado de
segundos ha transcurrido.
-O, --remote-name Escribe salida al archivo del mismo nombre como archivo
citado en la URL.
-u, --user Autenticar con par de nombredeusuario/contraseña.
nombredeusuario:contraseña
Por ejemplo, la siguiente línea de comandos podría utilizarse para descargar las imágenes ISO
para el lanzamiento de Fedora-Core 1:
445
[elvis@station elvis]$ curl -C - -O -L "http://download.fedora.redhat.com/pub/fe
dora/linux/core/1/i386/iso/yarrow-i386-disc{1,2,3}.iso"
[1/3]: http://download.fedora.redhat.com/pub/fedora/linux/core/1/i386/iso/yarrow
-i386-disc1.iso --> yarrow-i386-disc1.iso
% Total % Received % Xferd Average Speed Time Curr.
Dload Upload Total Current Left Speed
0 629M 0 536k 0 0 13375 0 13:42:49 0:00:41 13:42:08 75883
http://servername:puerto
La línea de comando del cliente de red wget diseñada para uso no interactivo de los protocolos
HTTP, HTTPS y FTP descarga recursos posiblemente de modo recursivo a las páginas citadas
desde las páginas descargadas.
Inicio de wget
Cuando se llama con una URL como su argumento, el comando wget recupera el contenido de la
URL y lo almacena en un archivo local en el directorio actual de trabajo del mismo nombre (o
index.html si el URL especificó un directorio).
El siguiente cuadro lista algunas de las opciones que pueden utilizarse para modificar la conducta
de wget. Encontrará una lista completa en la página del manual wget (1).
Opción Efecto
-i, --input-file filename Lea la URL para buscar desde el archivo filename, el cual puede ser
un archivo HTML o liste en modo secuencial el URL como texto.
-B, --base URL Anteponga URL a todos los enlaces relativos.
446
--spider No descargue páginas, solamente confirme su presencia.
--http-user=user --http- Autentique con el nombre de usuario especificado y la contraseña.
passwd=passwd
-o filename Concatene el contenido de todos los archivos descargados al
archivo filename. El nombre de archivo - especial implica una salida
estándar.
-r, --recursive Permite recuperar de modo recursivo.
-l, --level depth No es recursivo más allá de depth niveles de recursividad.
-np, --no-parent Al recursar, sólo incluya enlaces bajo el URL padre.
Por ejemplo, la siguiente línea de comandos sirve para copiar el contenido del sitio
http://www.redhat.com/training.
447
.
|-- certcities.com/
| `-- robots.txt
|-- rhn.redhat.com/
| `-- index.html
|-- secure.safaribooksonline.com/
| `-- promo.asp?code=ORA14&portal=oreilly
|-- www.europe.redhat.com/
| `-- robots.txt
|-- www.google.com/
| `-- robots.txt
|-- www.oreillynet.com/
| `-- robots.txt
`-- www.redhat.com/
|-- about/
| |-- careers/
| | `-- index.html
| |-- contact/
| | `-- index.html
| |-- corporate/
| | `-- wwoffices/
| | `-- index.html
| |-- index.html
| `-- presscenter/
| |-- 2002/
| | |-- press_bluepoint.html
| | |-- press_rhct.html
| | |-- press_training.html
| | `-- press_veterans.html
| `-- 2003/
| `-- press_rhacademy.html
|-- apps/
| |-- commerce/
| | `-- index.html
...
Igual al comando curl, wget utiliza la variable de entorno http_proxy para especificar un servidor
proxy, de nuevo utilizando la siguiente sintaxis.
http://servername:puerto
Ejemplos
El comando wget con opciones para intentar de nuevo puede ser útil para buscar archivos desde
un sitio ftp ocupado.
448
[einstein@station einstein]$ wget --tries=50 --wait=30 ftp://updates.redhat.com/
8.0/en/os/i386/wget-1.8.2-5.i386.rpm
--16:19:24-- ftp://updates.redhat.com/8.0/en/os/i386/wget-1.8.2-5.i386.rpm
=> `wget-1.8.2-5.i386.rpm'
Resolving updates.redhat.com... done.
Connecting to updates.redhat.com[66.187.232.52]:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done. ==> PWD ... done.
==> TYPE I ... done. ==> CWD /8.0/en/os/i386 ... done.
==> PORT ... done. ==> RETR wget-1.8.2-5.i386.rpm ... done.
Length: 365,737 (unauthoritative)
Al utilizar wget para copiar un sitio web, usted puede limitar el número de niveles de recursión.
Ejercicios en línea Lab Exercise Objetivo: Familiarizarse con la terminal basada en clientes
de red. Estimated Time: 10 mins.
Configurar
Si utiliza un servidor proxy para acceder a Internet, necesitará configurar sus clientes de red al
establecerhttp_proxy y/o las variables de entorno HTTP_PROXY. Su instructor le guiará.
Especificaciones
1. Cree el directorio ~/wget y cd dentro de éste. Utilice el comando wget para descargar de
modo recursivo el sitio www.redhat.com, pero utilice la opción -Q 256k para limitar su
descarga a un máximo de 256 kilobytes. Cuando haya terminado, su directorio ~/wget
debería contener el directorio www.redhat.com y posiblemente otros.
2. La CIA publica un libro mundial de datos de los países del mundo en el sitio
http://www.odci.gov/cia/publications/factbook/index.html. Más específicamente, URLs tales
como http://www.odci.gov/cia/publications/factbook/geos/ca.html se refieren a páginas del
país específico, en donde los países se especifican mediante un abreviatura de dos letras
en la porción del nombre de archivo de la URL.
Utilice el navegador de elinks para examinar una hoja de datos de todos los países
especificando la URL para la página del país directamente desde la línea de comandos.
Abbreviation País
as Australia
449
ch China
ni Nigeria
Después de familiarizarse con el formato de cada paǵina, escriba un script corto llamado ~/
bin/get_birthrate que combine los comandos curlygrep. El script debería esperar como su
único argumento una abreviatura de dos letras del país. Además, debería descargar la
página del país y reducir la salida a una línea que contenga la ¡nformación de la tasa de
natalidad del país.
Cuando haya terminado, el script debería generar una salida similar a la siguiente.
1. El directorio ~/wget que contiene los primeros 256 Kbytes (o más) de una descarga
recursiva del sitio web http://www.redhat.com
El script ~/get_birthrate, el cual cuando se invoca con una abreviatura de país de dos
letras, extrae la línea apropiada desde la URL
http://www.odci.gov/cia/publications/factbook/geos/ca.html (donde “ca.html” debería
remplazarse con la abreviatura apropiada).
450
Comandos remotos de shell
Conceptos clave
• Las aplicaciones remotas de shell le permiten a los usuarios ejecutar comandos arbitrarios
en máquinas remotas y tener salida estándar retornada de manera local. De modo alterno,
se puede iniciar una shell interactiva.
• La aplicación Secure Shell ofrece una shell remota, donde todas las transacciones son
encriptadas y los usuarios pueden autenticarse mediante contraseñas tradicionales o
esquemas de autenticación de clave pública.
• Para utilizar los esquemas de claves de autenticación pública, debe generarse un par de
claves pública-privada con el comando ssh-keygen.
• Debido a que los servidores de Secure Shell tienen sus propios servidores de pares de
claves pública-privada, los servidores pueden autenticarse para los clientes como también
los clientes se pueden autenticarse para los servidores.
Discussion
Las shells de Linux (y Unix) estan diseñadas con interfaces sencillas. Leen entrada desde el flujo
de la salida estándar. Como resultado, las interfaces se implementan fácilmente a través de
conexiones de red. Simplemente al sustituir una conexión TCP para un dispositivo de terminal, una
shell puede operar en una máquina remota de un modo tan fácil como la máquina local. En Linux (y
Unix), las aplicaciones que proporcionan esta funcionalidad se conocen como shells remotas.
La primera shell remota más utilizada fue la aplicación rsh. Si una máquina remota se configura
adecuadamente los usuarios pueden utilizar la línea de comandos rsh parecida a la siguiente para
invocar una shell remota.
Al traducir este comando dice "como el usuario elvis en el servidor 1 host, ejecuta el comando ls
/tmp". El comando se ejecuta en la máquina remota (server1), pero la salida estándar es enviada a
la máquina local (station). Cuando el comando termina, el intérprete de comandos de elvis implica
que aún está en la estación host.
Si elvis no especifica el comando a ejecutar, la utilidad rsh abre una shell interactiva en el server1
host. Al prestar atención al intérprete de comandos de bash en el siguiente extracto, observe qué
comandos se ejecutan y en qué máquina.
451
[elvis@station elvis]$ rsh -l elvis server1
Last login: Sat Nov 8 18:23:49 from station.example.com
[elvis@server1 elvis]$ hostname
server1.example.com
[elvis@server1 elvis]$ who
root tty1 Nov 8 16:56
root tty2 Nov 8 16:56
root pts/0 Nov 8 16:57 (:0.0)
elvis pts/4 Nov 8 18:28 (station)
[elvis@server1 elvis]$ exit
rlogin: connection closed.
[elvis@station elvis]$
En cada caso, elvis no necesitó expedir una contraseña. No obstante, antes de poder acceder a su
cuenta remota mediante rsh, necesitó configurar la cuenta para que le permitiera acceder desde su
máquina local. Para rsh, la configuración de control de acceso es tan trivial como agregar una línea
a un archivo. En una cuenta remota, elvis creó el archivo ~/.rhosts y agregó la línea con el host y el
nombre del usuario para cada cuenta externa a la cual quisiera otorgarle acceso. Además, el
servidor rsh requiere que los permisos de archivo le prohiban leer el archivo a todos con excepción
del usuario propietario. Así como se ilustra con el siguiente comando, elvis ya tiene configurado su
archivo .rhosts en la máquina remota.
La Shell segura
Además, rsh es un protocolo de texto sin formato. El intercambio de información a través de una
red en texto sin formato es esencialmente el equivalente a enviar correo en postales: todo el
mundo puede llevar la información de aquí a allá y no estar al tanto de su contenido.
La Shell segura se desarrolló para abordar estos dos defectos del comando rsh y agregar nuevas
capacidades mientras que aún ofrece toda la conveniencia de rsh. Si se asume que una máquina
remota está ejecutando el servicio ssh (i.e. el demonio sshd), elvis podría invocar una shell en la
máquina remota como se muestra a continuación.
452
[elvis@station elvis]$ ssh elvis@server1 ls /tmp
elvis@server1's password:
jd_sockV4
lost+found
orbit-root
[elvis@station elvis]$
La nueva sintaxis del comando ssh para especificar el nombre de usuario de la cuenta remota es
un poco más fácil que la de rsh, aunque la opción -l también se ejecuta (para ser completamente
compatible con los anteriores).
Aparte de la autenticación tradicional, la aplicación Shell segura puede utilizar una clave
criptográfica para autenticar usuarios. Los algoritmos de clave pública encriptada se relacionan con
dos grandes números conocidos como "claves" a fin de que la información encriptada con una
clave solo pueda ser descrifada con la otra. Cualquiera que quiera utilizar criptografía de clave
pública debe generar primero un par de claves. La mayoría de los protocolos de clave pública
llaman una clave como clave pública y la complementaria como una clave privada. A su clave
pública usted la trata como su número telefónico, el cual comparte con quien desee comunicarse y
que puede listar en directorios públicos. Su clave privada, por otra parte, no la comparte con nadie.
Toda la seguridad provista por los protocolos de clave privada dependen del hecho que sólo usted
conoce su clave privada.
Al utilizar ssh se puede generar un par de clave pública-privada con el comando ssh-keygen. La
shell segura puede utilizar diferentes algoritmos esenciales de encripción y el comando ssh-
keygen forzará a especificar uno con la opción -t. Para nuestros propósitos, utilizaremos el
algoritmo RSA, el cual se especifica con-t rsa. En el siguiente ejemplo, elvis utiliza ssh-keygen
para generar un par de clave pública-privada ssh-keygen.
Al usuario elvis primero se le pidió el nuevo nombre de archivo de clave (privada) para lo cual elvis
simplemente pulsó ENTER para aceptar el nombre de archivo predeterminado: ~/.ssh/id_rsa.
Luego, elvis tuvo la oportunidad de agregar una passphrase a su clave privada. Al pulsarENTER
453
otra vez (dos veces), elvis eligió no agregarla (más adelante trataremos las frases de acceso en
detalle).
Cuando el comando retorna, elvis tiene dos nuevos archivos en su directorio ~/.ssh. El primero
contiene su clave privada, la cual no la comparte con nadie (desde luego no la publica en un texto
en línea).
Él es libre de compartir su segunda clave (la clave pública) con quien se la pida.
El acceso de SSH a una cuenta se otorga obteniendo una copia de clave pública de la persona a
quien se le va a otorgar acceso y almacenándola en el archivo ~/.ssh/authorized_keys de la
cuenta. Como el archivo ~/.rhosts, el archivo ~/.ssh/authorized_keys debe ser legible sólo por el
usuario propietario del archivo. La forma de obtener una clave pública no interesa. Podría enviarse
por correo electrónico scp o transferirse desde una terminal a otra utilizando las utilidades de cortar
y pegar del ratón.
Cuando se manejan claves públicas, se debe tener mucho cuidado de asegurarse que la clave se
coloca en un archivo sin espacio incorporado, incluyendo líneas nuevas. Aunque es demasiado
para visualizar como tal, las claves públicas SSH, siempre se almacenan como una línea de texto
sencilla. A la mayoría de la gente puede otorgársele acceso a una cuenta simplemente agregando
sus claves públicas a los archivos ~/.ssh/authorized_keys, una clave pública en cada línea.
454
En el siguiente ejemplo, elvis utiliza ssh, redirección y algunas comillas colocadas cuidadosamente
para agregar su clave pública (en la station host) al archivo authorized_keys en su cuenta en el
server1 host.
¿Por qué son necesarias las comillas? Si las comillas se hubieran incluido, la salida del comando
cat se hubiera agregado al archivo .ssh/authorized_keys en la máquina local. Las comillas sirven
para pasar la sintaxis de redirección "en" la shell de red.
Algo no concuerda, porque a elvis se le solicitó otra vez su contraseña. Al recordar que los
permisos en el archivo ~/.ssh/authorized_keys deben ser 600, elvis ejecuta el comando chmod
apropiado en la máquina remota. Después, puede observar los nuevos permisos sin tener que
emitir una contraseña.
455
autenticación de clave pública, utiliza un procedimiento similar al siguiente. En nuestra discusión,
se utilizarán los siguientes símbolos.
Symbol Interpretación
S El contenido de la clave privada ("secreta") de elvis
P El contenido de la clave pública de elvis
R Una cadena de texto aleatoria
P(R) Una cadena de texto aleatoria encriptada por la clave pública de elvis
S(P(R)) = La cadena de texto es primero encriptada por la clave pública de elvis y luego
R descifrada por la clave privada de elvis.
Primero, el cliente ssh en la station host solicita una conexión al demonio sshd en el server1 host.
Tras recibir la solicitud de conexión, el demonio sshd busca una clave pública registrada en el
archivo ~/.ssh/authorized_keys de la cuenta de destino.
Si se descubre una clave pública relevante, el demonio sshd inicia la autenticación de clave
pública generando una cadena de texto aleatoria R. Luego encripta el guión aleatorio con la clave
pública de elvis P (obtenida desde el archivo ~/.ssh/authorized_keys) y envía el guión aleatorio
encriptado P(R) a través de la red al cliente ssh.
Tras recibir la cadena de texto encriptada de modo aleatorio P(R), el cliente ssh utiliza la clave
privada de elvis S para descifrala. Una vez se recupera la cadena de texto original aleatoria el
cliente ssh retorna al demonio sshd.
456
Si el demonio sshd recibe del cliente ssh la misma cadena de texto aleatoria con la cual inició, el
cliente se autentica y la conexión puede continuar.
En la práctica, el algoritmo real utilizado es más complicado. Sin embargo, el protocolo esbozado
anteriormente ilustra la mayoría de las características de la autenticación de protocolo de clave
pública.
457
Transferencia de archivos de modo seguro y fácil: scp
Como se ilustra en la discusión anterior, los archivos se pueden transferir de una máquina a otra
mediante ssh con el comando cat y una redirección cuidadosa. Afortunadamente, hay una forma
más fácil y menos propensa al error: scp.
El comando scp utiliza una sintaxis casi idéntica a la del comando cp, pero cualquier archivo o
archivos de origen o destino pueden estar en una máquina remota, que ha tenido acceso a través
de una cuenta especificada [1]. Cuando se refiera al archivo en una máquina remota, se utiliza la
siguiente sintaxis.
user@host:ruta
El usuario y host son simplemente el equipo en donde reside el archivo y el usuario cuya cuenta se
utiliza para acceder el archivo. Si la ruta del archivo comienza con un “/”, se considera como una
referencia absoluta. Si no, se considera como una referencia relativa del directorio de inicio del
usuario. Si no se provee una ruta, se asume que es el directorio de inicio del usuario.
Dado que elvis ha configurado correctamente la autenticación de clave pública con su cuenta en
server1, puede transferir el archivo sin emitir una contraseña. ¿Qué sucede si trata de transferir el
archivo /etc/shadow?
El usuario elvis en el server1 host no tiene permisos para leer el archivo /etc/shadow, por lo tanto
no puede ser transferido naturalmente. Sin embargo, si el usuario elvis conoce la contraseña de la
cuenta de root en la máquina remota, puede acceder el archivo a través de ella.
Puesto que elvis no tiene una clave de acceso pública autenticada para la cuenta de root server1,
ssh utilizó la autenticación tradicional de contraseña.
458
[elvis@station elvis]$ scp -r /etc/sysconfig elvis@server1:/tmp
ifup-aliases 100% |*****************************| 13137 00:00
ifcfg-lo 100% |*****************************| 254 00:00
ifdown 100% |*****************************| 3676 00:00
ifdown-ippp 100% |*****************************| 820 00:00
ifdown-ipv6 100% |*****************************| 4076 00:00
...
La primera vez que el cliente ssh (o scp) se utiliza para conectarse a un servidor Secure Shell
sshd, se presenta un mensaje similar al siguiente:
Si la respuesta del usuario es sí (la única respuesta que permite continuar a la conexión), la
conexión continúa con la siguiente advertencia.
La Secure Shell no sólo autentica clientes a servidores, sino también servidores a clientes,
mediante la autenticación de clave pública. Así como los usuarios pueden crear pares de clave
pública-privada con el comando ssh-keygen, el demonio sshd mantiene su propio par de claves
pública-privada conocido como su host key. La primera vez que un cliente ssh se conecta a un
demonio sshd, añade una copia de la clave del host público del demonio remoto al archivo local
~/.ssh/known_hosts.
459
Como el cliente se utiliza para conectarse a varias máquinas, el archivo ~/.ssh/known_hosts crece,
registrando una clave pública para cada máquina contactada. La próxima vez que el cliente se
conecta a un host, silenciosamente emplea el mismo protocolo de clave pública utilizado para
autenticar usuarios, invertido, para autenticar el host al cual se está conectando.
¿Qué sucedería si el host remoto no tiene la misma identidad complementaria de la clave pública
almacenada en el archivo de cliente ~/.ssh/known_hosts? El cliente rehusa conectarse y en su
lugar emite la siguiente advertencia.
Aquí, el cliente ssh está identificando la línea desde el archivo ~/.ssh/known_hosts con la
clave que ya no complementa el servidor.
Suele haber una explicación razonable para el cambio de identidad del servidor. Por ejemplo, el
servidor pudo haber sido actualizado con una versión más reciente de su sistema operativo y como
resultado, generó un nuevo par de clave pública-privada. Si hay una explicación razonable para
que un servidor cambie de identidad, el cliente ssh puede ser forzado a quitar la línea incorrecta
del archivo ~/.ssh/known_hosts y recoger una nueva clave para el host.
El emperador julius recientemente se ha suscrito a la línea DSL en la casa y quisiera tener acceso
a la información en su máquina principal desde el trabajo. En su máquina principal, agregó una
cuenta para él mismo utilizando su apodo,jules. No sabe el nombre de host del computador en su
460
casa, pero antes de salir a trabajar anotó su dirección IP 69.57.97.126. En la oficina, utiliza una
máquina con un nombre de host emporer.rome.gov y su nombre de cuenta es julius.
Como esta es la primera vez que ha tenido acceso a su máquina principal utilizando ssh, acepta la
clave del host al contestar si. En la siguiente solicitud de contraseña, entra la contraseña para su
cuenta de inicio de sesión.
Ahora Julius está contento porque puede tener acceso a su cuenta de inicio.
Ahora que Julius sabe que puede acceder a su cuenta de inicio de sesión, desearía configurar la
autenticación de la clave pública, para poder ordenar directamente a su máquina principal desde la
oficina, sin tener que emitir una contraseña. Inicia generando un par de clave pública-privada en su
máquina de trabajo, mediante el algoritmo RSA. Puesto que la configuración por defecto es
apropiada para él, escasamente pulsa la tecla ENTER para todas las preguntas asociadas.
Después de confirmar que sus archivos de clave pública-privada existen, utiliza el comando scp
para copiar su clave pública desde su equipo de trabajo al archivo .ssh/authorized_keys en su
máquina principal, autenticándose otra vez con su contraseña.
Aparentemente, ~/.ssh no existe aún. Julius remedia el problema y luego transfiere el archivo con
éxito. Por último, establece los permisos en el directorio remoto ~/.ssh y su contenido para que
sólo puedan estar disponibles para el usuario propietario.
461
[julius@emperor julius]$ ssh [email protected] mkdir .ssh
[email protected]'s password:
[julius@emperor julius]$ scp .ssh/id_rsa.pub
[email protected]:.ssh/authorized_keys
[email protected]'s password:
id_rsa.pub 100% |*****************************| 226 00:00
[julius@emperor julius]$ ssh [email protected] chmod -R go-rwx .ssh
[email protected]'s password:
Con su autenticación de clave pública ahora configurada, Julius puede acceder fácilmente a su
máquina principal.
En su máquina principal. Julius tiene un directorio llamado archivos, el cual contiene documentos
importantes. El desearía hacer una copia de seguridad del archivo en su máquina de trabajo.
Desde su máquina de trabajo, emite la siguiente línea de comandos.
Julius coloca un “-” donde sería especificado el nombre de archivo del archivo que se va a crear.
Este le pide al comando tar botar el archivo a la salida estándar en lugar de ponerlo en un archivo.
Localmente, la salida estándar fue redirigida al archivo jules.archive.tgz, Julius ha creado ahora
un archivo local del archivo remoto ~/archive como se confirma con el siguiente comando.
Ejercicios en línea
Lab Exercise Objetivo: Utilizar correctamente la aplicación Secure Shell. Estimated Time: 30
mins.
Especificaciones
462
2. Mediante su cuenta primaria, cree un script llamado ~/bin/send_to_a que copiará un
archivo regular como su único argumento en su directorio de inicio de su primera cuenta
alterna.
3. Mediante su cuenta primaria, cree un script llamado ~/bin/backup_c, el cual crea un archivo
tar gzipped del contenido de su directorio de inicio de la tercera cuenta alterna dentro del
archivo /tmp/backup_c.tgz.
1. La configuración correcta para que su cuenta primaria puede tener acceso a su primera y
tercera cuenta mediante ssh sin especificar una contraseña.
2. En su cuenta primaria, un script llamado ~/bin/send_to_a, el cual copiará un archivo regular
especificado como su único argumento dentro de sus primeras cuentas primarias de
directorio de inicio.
3. En su cuenta primaria, un script llamado ~/bin/backup_c, el cual crea un archivo tar
gzipped del contenido de su tercera cuenta alterna del directorio de inicio dentro del
archivo /tmp/backup_c.tgz.
463
Network Applications
Navegación del sistema de archivos
Conceptos clave
Discussion
Por ejemplo, la usuaria alice podría tener varias canciones almacenadas en archivos con nombres
como song1.midi y song2.midi. Estas canciones se podrían agrupar en un directorio llamado songs.
La usuaria alice también podría tener algunas fotos almacenadas en los archivos picture1.png y
picture2.png y a su vez, podría haberlos agrupado en un directorio llamado photos. Los dos
directorios songs y photos se pueden organizar en un directorio llamado media. Este nuevo
directorio puede ser uno de tantos en el directorio website.
Una manera de visualizar esto es por medio de una estructura ramificada de árbol. El directorio
website puede contener los subdirectorios html, formsy media. Junto con los directorios y los
archivos nombrados anteriormente, este orden se puede bosquejar como aparece en la gráfica 1-1.
464
-- html
|
website -- -- forms
|
| -- song1.midi
| |
| -- songs --
| | |
| | -- song2.midi
| |
-- media --
| -- picture1.png
| |
-- photos--
|
-- picture2.png
Linux utiliza un sólo árbol de directorios para toda su colección de archivos y directorios, todas las
ramas de una sola raíz "/" (léase como "barra oblicua") llamada directorio raíz. Este árbol de
directorios se puede ver, en parte, como se muestra en la gráfica 1-2.
-- bin...
|
/ -- -- etc...
|
| -- mystuff...
| |
| -- alice --
| | |
| | -- website...
| |
-- home --
| | -- docs...
| | |
| -- elvis --
| |
| -- graphics...
...
Las elipses en el diagrama sugieren que hay muchos archivos y directorios que no se muestran
aquí. Por ejemplo, puede ver que el directorio website trazado anteriormente puede adjuntarse
para extender el diagrama. La característica más importante del diagrama en este punto es la
estructura arbórea que se desprende de / y no el contenido específico.
465
Al nombrar un archivo o directorio, comience desde la raíz del árbol del sistema de archivos Linux y
liste todas las ramas del directorio hasta el archivo o directorio deseado, separando cada parte con
una barra oblicua (/). Esto se conoce como el nombre completamente calificado o FQN. Por
ejemplo, el FQN del directorio website, mencionado anteriormente, sería /home/alice/website. El
archivo song1.midide la usuaria alice se identificaría como /home/alice/website/songs/song1.midi.
La cadena de nombres de directorios que le llevan al nombre de archivo es la ruta del archivo. Este
tipo de nominación, ayuda a garantizar que cada archivo y directorio tenga un nombre único
completamente calificado. En la práctica real, los atajos y las suposiciones por defecto se utilizan
para simplificar el tecleado de los nombres de los archivos.
En el entorno gráfico X de Red Hat Enterprise Linux, los usuarios pueden utilizar Nautilus como
una herramienta sofisticada para navegar en el sistema de archivos. En el escritorio de Red Hat
Enterprise Linux, se puede abrir una ventana de Nautilus al hacer doble clic (izquierdo) en el icono
de inicio que se encuentra en la esquina superior izquierda.
Como una alternativa, usted puede utilizar el navegador Nautilus (puede ser más sencillo para
aquellos que han tenido contacto con lanzamientos previos de Red Hat Enterprise Linux) al
seleccionar el "navegador de archivos" desde el menú principal de Aplicaciones. [1]
Para poder explorar el árbol de directorios utilizando Nautilus, primero tenemos que activar el panel
lateral de Nautilus. Esto puede hacerse seleccionando el "panel lateral" desde el menú "ver".
La aplicación de panel lateral deNautilus se utiliza para diferentes propósitos. En este momento,
estamos interesados en explorar el árbol de directorios, así que seleccione "árbol" en el panel
lateral superior del menú.
El panel lateral de Nautilus le debe mostrar ahora la lista de directorios (carpetas) en forma de
árbol con el directorio superior llamado simplemente /. Un directorio se puede expandir al hacer clic
(en el botón izquierdo del ratón) en el triángulo al lado del icono de la carpeta. Cuando haga click
466
en el icono de la carpeta o en el nombre de carpeta, podrá ver el contenido de la carpeta en el
panel principal de Nautilus.
Tenga en cuenta que cuando se selecciona un directorio particular para ver, la entrada de "Buscar"
que se encuentra justo arriba del panel principal, muestra una referencia absoluta (FQN) para el
directorio que se está viendo. Dedique un poco de tiempo para explorar el sistema de archivos con
Nautilus y para ver el contenido de varios directorios. Intente ver el contenido del archivo
/etc/sysconfig/network-scripts/ifcfg-lo, primero seleccionando el directorio /etc/sysconfig/network-
scripts en el panel lateral y después, haciendo doble clic (en el botón izquierdo del ratón) en el
icono ifcfg-lo en el panel principal.
A cada proceso Linux (por ejemplo,un programa o un comando) cuando se ejecuta, se le asigna un
directorio por defecto. Este directorio por defecto se utiliza para completar el FQN para cualquier
archivo cuyo nombre no se especifique como un FQN. Esto tiene dos efectos. Primero, le permite
al proceso referirse a los archivos de una manera más sencilla sin tener que utilizar nombres
demasiado largos. Segundo, le permite al proceso operar con mayor flexibilidad ya que sus
acciones dependen en parte del directorio por defecto. Si cambia el directorio por defecto, la acción
del proceso también cambiará. A este directorio por defecto se le conoce como el directorio actual
de trabajo ó cwd, para el proceso.
Un método común que puede utilizarse con los directorios es el considerar un directorio como un
lugar más que una cosa. Desde este punto de vista entonces el cwd para un proceso se puede
considerar como la ubicación actual de un proceso. Si un proceso cambia de cwd entonces se ha
movidode un directorio a otro. Esta manera de ver un directorio como un "lugar" es tan común en el
mundo de Linux que la palabra lugar es bastante dominante en el lenguaje. Por ejemplo, los
usuarios hablan de navegar el sistema de archivos cuando se mueven de un directorio a otro.
En primer lugar, el padre del proceso que lo inicia le asigna un cwd al proceso. Sin embargo, un
proceso no está sujeto todo el tiempo a un determinado cwd cuando ejecuta. Cuando sea
necesario, un proceso puede cambiar su cwd a otro directorio antes de continuar su trabajo.
Como cualquier otro proceso, la shell bash se mantiene al tanto de su cwd mientras está
ejecutando. El directorio de trabajo actual afecta los comandos que usted escribe en el intérprete
de comandos y se convierte en su cwd mientras ejecutan. Básicamente entonces, el cwd de la
shell bash es su cwd, y puede considerarse como el lugar en donde usted se encuentra dentro del
sistema. Obviamente, es importante estar al tanto del cwd. Afortunadamente, hay ayuda disponible.
467
Primero, el mismo intérprete de comandos muestra el último directorio de la ruta al cwd. Por
ejemplo, la usuaria alice, al trabajar en su directorio website, puede ver un intérprete de comandos
como éste:
[alice$station website]$
El intérprete de comandos le recuerda que ha iniciado la sesión con el nombre de usuario "alice" en
la "estación," del computador y se encuentra en el directorio website. Pero pueden haber otros
directorios website en alguna otra parte del sistema. La ruta completa (o absoluta) del directorio de
trabajo actual se puede visualizar con el comando pwd (del inglés print working directory).
Uso:
pwd
La usuaria alice quiere verificar si se encuentra en el directorio correcto. Podría utilizar pwd.
Como se anotó anteriormente, los procesos pueden cambiar sus cwd cuando sea necesario. Esto
incluye la shell de comando bash, la cual proporciona el comando cd (del ingleś change directory)
para cambiar el directorio actual desde el intérprete de comandos.
Uso:
cd [DIRECTORIO]
Observe cómo cambia el resultado del comando pwd y la última parte del intérprete de comandos
para reflejar el nuevo cwd después de cada comando cd.
Puesto que navegar por los directorios es tan importante, hay abreviaturas especiales para hacer
referencia a ciertos directorios:
468
Table 1. Nombres de directorios especiales
Symbol Significado
. The current working directory
.. El directorio padre
~ The user's home directory
- El directorio de trabajo anterior
Las entradas en esta tabla requieren poca explicación. Primero, bash reconoce todos menos el
último nombre simbólico en la mayoría de los contextos, no sólo en el comando cd. Segundo, el
árbol de directorios se describe generalmente utilizando la analogía padre/hijo. Si dir1 contiene a
dir2, entonces se dice que dir2 es el directorio hijo de dir1 y que el dir1 es eldirectorio padre del
dir2. Por lo tanto, el directorio .. está a un nivel más cerca de la raíz del árbol de lo que se
encuentra el cwd. Después se le asigna un directorio de inicio a cada cuenta de usuario,
usualmente un subdirectorio de /home que coincide con su nombre de usuario (este tema se
explicará más detalladamente en el siguiente capítulo). El directorio ~ representa ese directorio.
Finalmente, la raya (-) es una opción especial del comando cd que se refiere al directorio de
trabajo anterior, facilitando el cambio entre directorios hacia adelante y hacia atrás.
La última serie de comandos en el ejemplo anterior muestra que por defecto el comando cd usa el
directorio ~ si no se le asigna un directorio.
Esta sección describe dos maneras de identificar la ubicación de un archivo. En esta sección, como
casi en cualquier otra parte de estas lecciones, es importante recordar que en Linux un directorio
es un tipo de archivo, así que todo lo que se diga sobre nominación de archivos, también aplica a
directorios y a archivos comunes de datos.
Para identificar un archivo, se debe proporcionar suficiente información para localizar el archivo
dentro del sistema de archivos. Esta ubicación se puede proporcionar de dos maneras: como
referencia absoluta(o ruta absoluta) o como referenciarelativa.
Las referencias absolutas inician con una barra oblicua (/) y asignan el FQN del archivo. Es decir,
la referencia absoluta nombra cada rama del árbol de directorio del sistema de archivos, a partir
469
de /, la cual se debe recorrer hasta llegar al archivo. Sin importar en dónde se encuentre usted en
el sistema de archivos, (en otras palabras, sin importar el valor del cwd), una referencia absoluta
identifica claramente el recurso específico. Ya hemos discutido varios ejemplos de referencias
absolutas en esta lección.
Una referencia relativa no describe la ruta al archivo desde /, sino que describe la ruta a partir del
directorio actual. Por ejemplo, si el cwd es /home/alice, entonces la referencia relativa a song1.midi
puede ser website/songs/song1.midi. Esta es una referencia relativa ya que no comienza con /.
Esta referencia sólo nombra los directorios que se deben recorrer iniciando desde /home/alice, no
desde /. Para que una referencia relativa sea válida debe iniciar nombrando un directorio (o
archivo) en el cwd.
Todos los directorios en Linux contienen dos entradas especiales, los directorios . y .., los cuales
representan el directorio actual y el directorio padre, respectivamente. Por lo tanto, en la discusión
previa acerca del comando cd, el ejemplo cd .. era en realidad sólo un uso de una referencia
relativa.
La tabla 1-2 muestra algunos ejemplos adicionales sobre referencias relativas. Cada uno de estos
es una referencia al archivo /home/alice/sample.txt con FQN. Algunos de estos ejemplos son
intencionalmente "ineficaces."
Ejemplos
Hogan acaba de inciar sesión y no se ha dado cuenta de que, por defecto, su directorio de inicio se
encuentra asignado como su cwd. Además, tampoco se ha dado cuenta de que su directorio de
inicio es /home/hogan. Se dispone a descubrir cuál es su directorio de inicio y también quiere ver si
de hecho su cwd por defecto es su directorio de inicio.
470
Subir y bajar del árbol
Alice necesita editar algunos de los archivos html en su sitio web. Después de iniciar la sesión
necesitará cambiarse al subdirectorio apropiado bajo su directorio de inicio. Cuando lo haya hecho,
deberá ir a /etc para examinar el archivo de configuración. Finalmente, tendrá que devolverse a su
directorio de inicio para empezar a trabajar en otra tarea.
Ejercicios en línea
Explorar el sistema de archivos Lab Exercise Objetivo: Demostrar el uso de cd.Estimated Time:
10 mins.
Especificaciones
En este ejercicio tendrá que configurar el directorio actual de trabajo de cuatro shells bash
ejecutando de manera simultánea. Si está utilizando el entorno gráfico X puede simplemente abrir
cuatro terminales. Si está utilizando consolas virtuales, puede utilizar cuatro de las seis consolas
virtuales provistas.
Abra cuatro terminales con shells bash (como se describió anteriormente) utilizando su cuenta
primaria. Utilice el comando cdpara establecer los directorios de trabajo actuales de las shells en
los siguientes cuatro directorios:
1. ~/..
2. /tmp
3. /etc/sysconfig
4. /usr/share/gnome
1. Cuatro shells bash ejecutando de manera simultánea con cada directorio de trabajo actual
de shell establecido en uno de los cuatro directorios listados anteriormente.
471
Possible Solution
472
Directorios importantes
Conceptos clave
Discussion
Linux se puede utilizar para soportar muchos tipos diferentes de sistemas informáticos: servidores,
estaciones de desarrollo, sistemas de escritorio personales, etc. Para poder estandarizar la
estructura del directorio del sistema de archivos a través de este variado rango de sistemas, la
mayoría de los sistemas Linux emplean un esquema de nominación y utilización común que
facilitan el uso y el mantenimiento de los sistemas. Al utilizar el mismo tipo de diagrama arbóreo
empleado en el último capítulo, parte de la primera capa del árbol de directorios se vería así:
-- bin...
|
-- etc...
|
-- home...
|
-- root...
/ --|
-- sbin...
|
-- tmp...
| -- bin
-- usr --|
| -- sbin
-- var...
Este capítulo presenta una breve descripción (a veces muy breve) del papel de cada uno de estos
directorios.
A cada usuario del sistema Linux se le asigna un directorio especial llamado su directorio de inicio
y representa su espacio "privado" en el sistema. Comúnmente éste es un subdirectorio bajo el
directorio /home, cuyo nombre coincide con el nombre de inicio de sesión del usuario (se vieron
varios ejemplos anteriormente /home/alice o /home/hogan). La única excepción importante a esto
es el superusuario (o el usuario root) cuyo directorio de inicio usualmente es /root. Para cualquier
473
usuario, el caracter (~) representa el FQN del directorio de inicio del usuario cuando se utiliza como
el primer caracter de una referencia de archivo o directorio.
El propósito más obvio para el directorio de inicio de un usuario es brindar un espacio privado para
datos, un lugar en donde se pueden guardar archivos separados de los archivos de otros usuarios.
Normalmente, los usuarios son libres de crear subdirectorios bajo su directorio de inicio y de
organizar sus datos como les parezca (sujetos a las restricciones de cuotas que deben haber). Dos
usuarios diferentes pueden incluso asignar el mismo nombre a archivos y directorios sin causar
ningún conflicto ya que cada uno almacena en su propio espacio. Por ejemplo, tanto Alice como
Hogan pueden tener cada uno su subdirectorio public_html, /home/alice/public_html y
/home/hogan/public_html respectivamente. El mantener el espacio de cada uno separado de los
otros, ofrece también más seguridad a los usuarios.
Otro aspecto importante del directorio de inicio de un usuario es que proporciona un lugar para
almacenar archivos de configuración específicos para cada usuario. Por ejemplo, cuando Blondie
inicia la sesión puede que necesite un entorno diferente al de Prince. Puede que Blondie prefiera
diferentes colores en su pantalla, diferentes atajos de comandos e inclusive un entorno de
escritorio de trabajo completamente diferente al de Prince. Los archivos de configuración locales
específicos para cada usuario hacen que esto sea posible. Muchos de estos archivos de
configuración se crean automáticamente por defecto cuando se crea la cuenta de un usuario o al
utilizar por primera vez un recurso en particular del sistema.
Cuando un usuario inicia sesión en el sistema por primera vez se le ubica "en" su directorio de
inicio, es decir, el sistema configura su directorio de inicio como su directorio de trabajo inicial.
Además de su espacio personal en sus directorios de inicio, se le da acceso a los usuarios para
compartir espacio de "borrador", en el directorio /tmp. Un programa que necesite almacenar datos
comprimidos puede almacenar resultados parciales en /tmp, sólo poniendo los resultados finales
en el directorio de inicio del usuario cuando haya terminado de hacerlo. Con frecuencia los
sistemas Linux implementan cuotas en cuentas de usuarios para prevenir que cualquier usuario
consuma una proporción injusta del espacio disponible. El directorio /tmp le da a todos los usuarios
acceso a espacio adicional para cumplir con necesidades a corto plazo sin cargar el espacio en su
cuota. Esto es especialmente importante, ya que los usuarios no siempre son conscientes de
cuánto espacio extra necesita un servicio y algunos servicios (tal como X) no pueden ejecutar si no
hay espacio temporal disponible de almacenamiento. Este espacio de borrador "global" se
encuentra disponible para todos los procesos en el sistema así como para todos los usuarios. El
sistema borra automáticamente los archivos puestos en este directorio después de unos días.
474
sysconfig. Obviamente, los usuarios comunes no pueden modificar los archivos en /etc (o incluso
leerlos, en algunos casos), pero los administradores de sistemas invierten bastante de su tiempo
trabajando con los archivos almacenados aquí.
La mayoría de los comandos del sistema se encuentran almacenados como archivos binarios en
un formato legíble para la máquina. Los comandos apropiados para el uso de usuarios comunes se
suelen ubicar en los directorios binarios /bin o /usr/bin. Las utilidades más importantes como ls, cd,
cp, mv y el editor de texto vi, sin los cuales no se podría usar el sistema van en /bin. Las utilidades
adicionales como los compiladores, su navegador de web y la suite de oficina van en /usr/bin, los
cuales se pueden poner a disposición de otros sistemas a través de la red. Considere /bin y /usr/bin
como directorios de comandos no privilegiados ya que no se necesitan privilegios especiales para
utilizar los comandos que se encuentran en ellos.
Considere /bin y /usr/bin como directorios de archivos no privilegiados puesto que no se requieren
privilegios especiales para utilizar los comandos que se encuentran en ellos.
Así como /bin y /usr/bin almacenan archivos de comando para usuarios comunes, también /sbin y /
usr/sbin almacenan archivos de comandos para que el superusuario root los utilice. Estos incluyen
comandos para adjuntar y quitar hardware, para iniciar y detener el sistema y para realizar
mantenimiento del sistema. Estos comandos privilegiados también se encuentran almacenados en
dos directorios separados por las mismas razones que para /bin y /usr/bin.
Es un desafortunado accidente de la historia que el término raíz tenga un papel tan importante y a
la vez confuso en Linux. La raíz o el "root" en inglés, es el nombre de usuario del superusuario, es
decir, el usuario con autoridad suprema sobre el sistema. También es el nombre del directorio de
inicio de ese usuario, /root. Igualmente, es el término que se utiliza para la base (¿la parte
superior?) del árbol de directorios del sistema de archivos, el directorio /. Normalmente, el
significado del término se puede deducir del contexto, pero una oración tal como el "directorio raíz"
puede llegar a ser ambigua. Trate de anticipar y de evitar tal confusión en su propia comunicación y
busque aclaración si el significado de la palabra no se puede deducir fácilmente del contexto.
Ejemplos
El directorio /tmp
475
Alice acaba de aprender que algunos de los procesos utilizan automáticamente /tmp como espacio
de borrador y quiere ver si algo de lo que ha hecho ha utilizado ese espacio. También quiere
probar si realmente puede crear archivos allí.
Después de cambiar a /tmp, Alice usa ls y ls -l para ver el contenido del directorio /tmp.
Aunque ls -l produce un listado largo, ella no está segura y ve su nombre de usuario tantas
veces que se convence de que algunos programas que ejecutó dejaron archivos en /tmp,
como le habían dicho antes. De hecho, tanto orbit-alice como ssh-XXDg4ke3 fueron colocados
allí cuando ella inició su entorno de escritorio.
Alice utiliza el comando touch para crear un nuevo archivo vacío llamado newfile en /tmp.
Como muchos de los comandos Linux cuando touch lo logra, lo hace de manera silenciosa
(sin ningun aviso en la pantalla). Alice verifica que touch sí funcionó con otro ls -l.
Hogan quiere ver si algunos de los comandos comunes que utiliza se encuentran en alguno de los
directorios de los comandos binarios /bin o /usr/bin. Decide probar cp, mozilla, cd y fdisk.
Hogan puede utilizar ls para buscar estos comandos, pero en su lugar quiere probar un nuevo
comando, which.
Uso sencillo:
which PROGRAM
Muestra el FQN del archivo del comando PROGRAM que se utilizará si el usuario ejecuta el
comando.
476
[hogan@station hogan]$ which cp
/bin/cp
[hogan@station hogan]$ which mozilla
/usr/bin/mozilla
[hogan@station hogan]$ which cd
/usr/bin/which: no cd in
(/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/hoga
n/bin:)
[hogan@station hogan]$ which fdisk
/usr/bin/which: no fdisk in (/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/
home/h
ogan/bin:)
[hogan@station hogan]$ ls /sbin
...
ether-wake ldconfig portmap usbmodules
extendfs lilo poweroff vboxd
fdisk logdump pppoe vgcfgbackup
...
Hogan ve que cp se encuentra en el directorio /bin, lo cual le parece posible ya que los archivos
en /bin son los archivos que los usuarios normales desearían que siempre estuvieran presentes en
el sistema.
Hogan encuentra mozilla (el navegador que escogió) en /usr/bin. Esto también parece estar bien
ya que los archivos en /usr/bin son archivos que un usuario normal podría querer que no siempre
estuviesen disponibles.
Hogan está sorprendido de los resultados de cd, lo cual parece decir que el comando cd no está
en el sistema. Estaba esperando ver una respuesta como /bin/cd. (¿Por qué?) Lo que Hogan no
sabe es que cd es un ejemplo de un comando interno, provisto por el comando de la shell bash.
Por otro lado, si revisara, encontraría bash en /bin.
Hogan también está sorprendido de los resultados de fdisk. Sabe que es un comando
importante, pero peligroso, utilizado para particionar discos y sólo debe estar disponible para el
superusuario así que estaba esperando una respuesta de /sbin. Incluso puede ver fdisk en /sbin
cuando lo examina utilizando ls. Al mirarlo más detenidamente, descubre que which ni siquiera
buscó fdisk en /sbin. Después Hogan aprenderá sobre la ruta de comandos y descubrirá el porqué
esto tiene perfecto sentido.
Ejercicios en línea
Configuración
En este ejercicio necesitará utilizar touch para crear archivos. Este comando se demostró en los
ejemplos de este capítulo. Necesitará utilizar which para ubicar los archivos de comando. Este
comando también se demostró en los ejemplos.
Especificaciones
1. Abra una nueva terminal o una nueva consola virtual (esto se necesita para la evaluación
de su trabajo en línea).
477
Quiere probar si en realidad puede utilizar touch para crear archivos en varios directorios.
Espera que esto funcione en su directorio de inicio y en /tmp, pero no en otros directorios.
Use el comando touch newfile.username (en donde el username se remplaza con su
nombre de usuario) en cada uno de los siguientes directorios.
a. ~
b. /tmp
c. /bin
d. /root
Claramente, cabe esperar que algunos de sus esfuerzos no den resultado. Regrese a su
directorio de inicio cuando haya terminado.
2. Utilizando which, determine el FQN del archivo del comando binario para cada uno de los
siguientes: pwd, ls y whoami. Ejecute cada uno de estos comandos de manera "cruda"
utilizando el FQN en el intérprete de comandos. Finalmente, ejecute exit, salga de la
terminal o de la consola virtual.
Cuando haya terminado, salga de su shell para que se guarde la historia de sus comandos en el
archivo ~/.bash_history.
Possible Solution
478
Administración de archivos
Conceptos clave
Discussion
Redirección
A Linux le gusta pensar que todo es un archivo. En el ejemplo anterior, pwd envió la salida al
archivo de salida estándar, o STDOUT, el cual es por defecto la pantalla para los usuarios que han
iniciado sesión en el sistema.
Una de las características de la shell de comandos bash es que la salida que normalmente es
dirigida a la pantalla a través de STDOUT, también puede ser redireccionada a algún otro archivo.
Esto se hace utilizando el símbolo especial de redireccionamiento, , como se muestra en este
ejemplo:
[julius@station julius]$ ls
[julius@station julius]$ pwd > results.txt
[julius@station julius]$ ls
results.txt
En este ejemplo, los resultados usuales del comando fueron dirigidos al archivo results.txt, creando
el archivo durante el proceso. Un comando útil que nos puede servir para verificar lo que ha
pasado es el comando cat (concatenar).
Uso:
479
El comando cat copia cada uno de los archivos listados a la salida estándar. Si se lista más de un
archivo, esto concatena efectivamente los archivos. Como para cualquier otro comando, esta salida
se mostrará en la pantalla por defecto, pero también se puede redireccionar a un archivo. Lo
utilizaremos para mostrar un archivo nombrando un sólo archivo y no redireccionando los
resultados.
El comando más sencillo de todos que produce una salida visible es echo. El comando echo toma
cualquier texto que se teclee como parte del comando y lo repite a la salida estándar (usualmente
la pantalla). Este comando sencillo junto con el redireccionamiento, se puede utilizar para crear
archivos de texto.
Uso:
Example 1:
Ejemplo 2:
[julius@station julius]$ ls
[julius@station julius]$ pwd > results.txt
[julius@station julius]$ cat results.txt
/home/julius
[julius@station julius]$ ls >> results.txt
[julius@station julius]$ cat results.txt
/home/julius
results.txt
480
Copie archivos con cp
Uso:
De la primera manera, se hace una copia del archivo FUENTE como DESTINO. De la segunda
manera, se pueden copiar uno o más archivos al mismo tiempo a un directorio. Se hace una copia
del archivo FUENTE, ..., en el DIRECTORIO y se nombra DIRECTORIO/FUENTE, .... Con las
opciones apropiadas (no se discutirán aquí - intente man cp), puede copiar árboles de
subdirectorios completos de una sola vez.
Ejemplos:
cp mysong.midi backup.midi
cp mynovel.txt /tmp
cp ~/webpage.html .
Uso:
481
mv [OPCION...] {FUENTE...} {DIRECTORIO}
Ejemplos:
mv mysong.midi backup.midi
mv mynovel.txt /tmp
mv ~/webpage.html .
mv html public_html
482
mv images html
Uso:
rm [OPCIONES] {ARCHIVO...}
Note
Sí, el comando rm puede suprimir árboles enteros de directorios de una sola vez. En las
manos del susperusuario puede borrar el contenido completo de un sistema de archivos -- no
siempre es lo que se pretende hacer.
Warning
La documentación para rm incluye la siguiente frase: "Observe que si utiliza rm para suprimir
un archivo, usualmente es posible recuperar el contenido de ese archivo." Aunque esto pueda
ser verdad requiere un nivel de habilidad más allá del proposito de este curso, así que para
todos los propósitos prácticos, debe tratar este comando como si no fuese reversible.
Ejemplos:
1. Borrar mysong.midi:
rm mysong.midi
rm songs.tar novels.tgz
rm ~/photos.html
483
Sobrescribir archivos (¡uy!)
Algunas de las advertencias incluídas en la sección anterior insinúan algunos de los comandos
potencialmente peligrosos como cp, mv y rm. Infortunadamente, aunque por lo general, mientras
vemos pasar las corrientes del rio, con frecuencia olvidamos las rocas que se encuentran bajo el
agua y Linux también es el mismo caso. Este es el precio que hay que pagar por el poder de un
sistema operativo como Linux. En esta sección resaltamos uno de esos peligros: sobrescribir
archivos.
La redirección de comandos con > y los comandos cp y mv, pueden nombrar los archivos destino.
Normalmente, estos son nombres de archivos nuevos y los comandos crean los archivos. Pero si
se nombra un archivo existente como destino de la redirección, cp o mv, el archivo existente será
destruido sin advertencia. Esto se conoce como sobrescribir un archivo. Puesto que este problema
puede llegar a ser tan sorprendentemente sutil para un nuevo usuario, le vamos a mostrar varios
ejemplos.
Ejemplo 3:
Ejemplo 4:
Aquí tampoco hay sorpresas -- observe como mv remplazó el contenido previo de file1 sin ninguna
advertencia. De nuevo, file1 ha sido sobrescrito. cp habría remplazado file1 de la misma manera.
Para poder entender completamente nuestro último ejemplo, necesitamos aprender un poco más
acerca de redireccionamiento. En particular, necesitamos aprender cuándo se sucede la
redirección.
484
Ejemplo 5:
¿Por qué file2 lista file1 y file2, cuando el primer ls sólo muestra file1? Respuesta: debido a la
secuencia en que tuvieron lugar los pasos críticos. Evento 1: bash vio la redirección al archivo file2
y lo creó como un archivo vacio (vea la discusión anterior sobre redireccionamiento). Evento 2: ls
generó un listado de archivos mostrando el archivo creado anteriormente file1 y el que se acaba de
crear file2. Evento 3: la salida de ls se envió a file2.
Ejemplo 6:
Esto necesita una explicación. Primero, Julius crea mycwd usando pwd y presenta su contenido
con cat. Después utiliza cp para tratar de copiar el archivo a sí mismo pero cp detecta el "error,"
muestra un mensaje y no hace nada (mv hubiese hecho lo mismo). El cat en la línea siguiente
verifica que mycwd no ha tenido cambios. Está bien hasta ahora. Sin embargo, la siguiente
secuencia produce una gran sorpresa. Julius usa cat con redireccionamiento para tratar de copiar
un archivo a sí mismo. cat también se queja de los archivos fuente (entrada) y del destino (salida)
al ser el mismo y pareciese que no hace nada. Pero el cat final de mycwd no produce ninguna
respuesta -- ¡el contenido del archivo se perdio! ¿Por qué? Debido a la secuencia en la que
tuvieron lugar los eventos. Evento 1: bash ve la redirección a un archivo que ya existe, borra el
archivo y lo re-crea vacío (vea la discusión anterior sobre redirección) -- mycwd es sobrescrito.
Evento 2: ya no importa lo que cat haga puesto que el archivo fuente mycwd ya ha sido destruído y
re-creado. Es demasiado tarde para evitar el error.
485
parent home
Ejemplos
Madonna intentó configurar un sitio web personal simple, pero después de terminar su ISP le dijo
que había puesto todos los archivos del sitio web en un directorio equivocado. Puso los archivos en
~/html y debieron haber sido puestos en ~/public_html. Necesita mover los archivos al directorio
correcto. Mientras lo hace, también necesita hacer una copia de seguridad de los archivos que se
encuentran en el directorio archive, por si acaso daña o borra accidentalmente uno de los archivos
en ~/public_html. El directorio archive ya existe.
[madonna@station madonna]$ ls
html archive
[madonna@station madonna]$ mv html public_html
[madonna@station madonna]$ cd public_html
[madonna@station public_html]$ ls
index.html photo.jpeg
[madonna@station madonna]$ cp index.html photo.jpeg ../archive
Para mover los archivos todo lo que Madonna tuvo que hacer fue renombrar el directorio. Para
hacer copias de seguridad utilizó la habilidad del comando cp para copiar más de un archivo a la
vez.
Nero intentó configurar un sitio web personal simple, pero después de terminar su proveedor de
servicios de internet (ISP por sus siglas en inglés) le dijo que habia puesto todos los archivos del
sitio web en el directorio equivocado. Puso los archivos en su directorio de inicio y deben estar en
~/public_html. Necesita mover los archivos al directorio correcto. Su problema es más complicado
que el de Madonna, puesto que no puede renombrar un subdirectorio simplemente. El directorio
public_html fue creado por su ISP.
[nero@station nero]$ ls
index.html photo1.jpeg photo2.jpeg public_html
[nero@station nero]$ mv index.html photo1.jpeg photo2.jpeg public_html
[nero@station nero]$ ls
public_html
[nero@station nero]$ cd public_html
[nero@station public_html]$ ls
index.html photo1.jpeg photo2.jpeg
Para mover los archivos Nero utilizó la habilidad del comando mv para mover más de un archivo a
la vez.
Suprimir robots.txt
Elvis nota un archivo en su directorio ~/public_html que no reconoce, un archivo llamado robots.txt.
Decide borrarlo.
486
[elvis@station elvis]$ ls
public_html
[elvis@station elvis]$ ls public_html
index.html robots.txt
[elvis@station elvis]$ rm public_html/robots.txt
[elvis@station elvis]$ ls public_html
index.html
Ejercicios en línea
Crear un sitio web Lab Exercise Objetivo: Utilizar la redirección, cp y mv para crear un sitio web
simple y archivar el sitio web. Tiempo estimado: 15 minutos.
Configuracion
En este ejercicio necesitará trabajar con los directorios ~/html y ~/archive. Inicie sesión con su
cuenta y utilice los siguientes comandos para crear estos dos directorios:
Especificaciones
Quiere crear un sitio web personal simple utilizando las técnicas que se demostraron en la sección
de ejemplos de este capítulo.
Note
La página web resultante puede ser o no visible con un navegador, dependiendo de las
características adicionales de la configuración de su sistema. Su instructor le dirá si puede
ver los resultados de su trabajo de este modo.
Possible Solution
The following sequence of commands provides one possible solution to this exercise.
487
[student@station student]$ mkdir html archive
[student@station student]$ echo '<h1>' > index.html
[student@station student]$ echo 'Under construction' >> index.html
[student@station student]$ echo '</h1>' >> index.html
[student@station student]$ mv index.html html
[student@station student]$ mv html public_html
[student@station student]$ cp public_html/index.html archive
[student@station student]$ ls public_html
index.html
[student@station student]$ ls archive
index.html
Investigar la opción "noclobber" Lab Exercise Objetivo: Investigar las consecuencias de la opción
bash "noclobber". Estimated Time: 10 mins.
Especificaciones
Desea investigar las consecuencias del sobrescribir archivos y de la opción bash "noclobber".
1. Abra una nueva terminal o una nueva consola virtual (esto se necesita para la evaluación
de su trabajo en línea).
2. Cree un archivo llamado source que incluya la palabra "fuente" y un archivo llamado target
que incluya la palabra "destino."
3. Use cp para sobrescribir target con source. Verifique el efecto con cat.
4. Re-cree target.
5. Sobrescriba target de nuevo haciendo cat en source y redireccionando la salida. Verifique
los resultados.
6. Active la opción bash "noclobber" con el siguiente comando mágico:
Possible Solution
The following sequence of commands provides one possible solution to this exercise.
488
[student@station student]$ echo source > source
[student@station student]$ echo target > target
[student@station student]$ cp source target
[student@station student]$ cat target
source
489
Administración de directorios
Conceptos clave
Discussion
La organización de archivos dentro de directorios requiere la habilidad para crear los directorios
que necesita. En Linux, el comando para hacer un directorio nuevo es el comando mkdir (del
inglés make directory).
Uso:
Crea el(los) DIRECTORIO(s) si no existe(n). Falla y emite un mensaje de error si uno o más de los
DIRECTORIO(s) existen, pero los nuevos directorios restantes son aún creados.
[elvis@station elvis]$ ls
[elvis@station elvis]$ mkdir public_html
[elvis@station elvis]$ ls
public_html
Sin embargo, observe que por defecto, mkdir no creará un subdirectorio si el directorio padre no
existe de antemano:
490
Sólo si Elvis utiliza mkdir -p (como 'padre') puede crear un árbol de directorios completo de una
sola vez:
A title
Por ahora, tenga en cuenta que cuando se da un directorio como argumento al comando ls, éste
lista el contenido del directorio. ¿Pero qué pasa si el directorio contiene otros directorios? Por
defecto, el comando ls sólo mostrará el contenido del directorio del nivel más alto. Si también
quiere que el comando ls liste los subdirectorios, puede añadir la opción -R.
Por ejemplo, hogan está explorando la configuración de red de la máquina y sospecha que el
directorio /etc/sysconfig/networking es un directorio importante. Para poder descubrir los archivos y
los subdirectorios que contiene, hogan lista el contenido del directorio de modo recursivo.
/etc/sysconfig/networking/devices:
ifcfg-eth0
/etc/sysconfig/networking/profiles:
default netup
/etc/sysconfig/networking/profiles/default:
hosts ifcfg-eth0 network resolv.conf
/etc/sysconfig/networking/profiles/netup:
hosts ifcfg-eth0 network resolv.conf
ls -R también se puede combinar con cualquiera de las opciones de línea de comando vistas
anteriormente, tales como ls -sR para incluir los tamaños de archivos, o ls -lR para incluir los
atributos de archivos.
491
Borrar directorios (vacíos): rmdir
Uso:
Suprime el (los) DIRECTORIO(s) si están vacíos. Emite un mensaje de error si uno o más del (los)
DIRECTORIO(s) no está(n) vacío(s), pero los directorios que quedan (vacíos) se borran. Tenga en
cuenta que un directorio que contiene sólo un subdirectorio no se considera como vacío.
[elvis@station elvis]$ ls
public_html
[elvis@station elvis]$ rmdir public_html/images
[elvis@station elvis]$ ls
[elvis@station elvis]$
Como lo señalamos antes, observe de nuevo que los comandos tales como mkdir y rmdir
funcionan de manera silenciosa. Como dice el dicho el silencio es oro.
Por ahora, tenga en cuenta que cuando se da un directorio como argumento al comando ls, éste
lista el contenido del directorio. ¿Pero qué pasa si el directorio contiene otros directorios? Por
defecto, el comando ls sólo mostrará el contenido del directorio del nivel más alto. Si también
quiere que el comando ls liste los subdirectorios, puede añadir la opción -R.
Por ejemplo, a elvis le gustaría tener una lista de archivos y directorios más detallada en su
directorio ~/work. Recuerde que elvis antes tenía que emitir un comando ls por separado para cada
subdirectorio de ~/work con el fin de ver el contenido de subdirectorio. Ahora en su lugar, puede
utilizar la opción ls -R.
work/images:
advertising logos
work/images/advertising:
work/images/logos:
work/spreadsheets:
492
Observe que el comando anterior mostrará archivos así como directorios. En este ejemplo,
casualmente no hay ningún archivo para mostrar.
ls -R también se puede combinar con cualquiera de las opciones de línea de comando vistas
anteriormente, tales como ls -sR para incluir los tamaños de archivos, o ls -lR para incluir los
atributos de archivos.
En el capítulo anterior cuando se introdujo cp, señalamos que con las opciones correctas el
comando cp serviría para copiar árboles de directorios completos. Aquí analizamos dicha opción: -r
(de recursive) (Muchos de los comandos tienen la opción de actuar de modo recursivo es decir,
recorriendo todas las ramas de un sub-árbol de directorio, actuando en cada subdirectorio a su
vez).
-- html
|
hogan -- website -- -- forms
|
| -- song1.midi
| |
| -- songs --
| | |
| | -- song2.midi
| |
-- media --
| -- picture1.png
| |
-- photos--
|
-- picture2.png
Aunque este árbol de directorios contiene muchas ramas y archivos, se puede copiar con una sóla
orden:
493
-- html
|
-- website -- -- forms
| |
| | -- song1.midi
| | |
| | -- songs --
| | | |
| | | -- song2.midi
| | |
| -- media --
| | -- picture1.png
| | |
hogan -- -- photos--
| |
| -- picture2.png
|
| -- html
| |
-- archive -- -- forms
|
| -- song1.midi
| |
| -- songs --
| | |
| | -- song2.midi
| |
-- media --
| -- picture1.png
| |
-- photos--
|
-- picture2.png
494
-- html
|
-- website -- -- forms
| |
| | -- song1.midi
| | |
| | -- songs --
| | | |
| | | -- song2.midi
hogan -- | |
| -- media --
| | -- picture1.png
| | |
| -- photos--
| |
| -- picture2.png
-- archive
495
-- html
|
-- website -- -- forms
| |
| | -- song1.midi
| | |
| | -- songs --
| | | |
| | | -- song2.midi
| | |
| -- media --
| | -- picture1.png
| | |
hogan -- -- photos--
| |
| -- picture2.png
|
| -- html
| |
-- archive -- website -- -- forms
|
| -- song1.midi
| |
| -- songs --
| | |
| | -- song2.midi
| |
-- media --
| --
picture1.png
| |
-- photos--
|
--
picture2.png
En esta segunda demonstración, el directorio website es recreado dentro del directorio archive.
En el capítulo anterior cuando se introdujo rm, señalamos que con las opciones correctas, el
comando rm puede borrar por completo árboles de directorios. De nuevo, para cp la opción es -r
(derecursivo).
496
-- html
|
hogan -- website -- -- forms
|
| -- song1.midi
| |
| -- songs --
| | |
| | -- song2.midi
| |
-- media --
| -- picture1.png
| |
-- photos--
|
-- picture2.png
-- html
|
hogan -- website --
|
-- forms
Vale la pena anotar una vez más que, en general, el borrar archivos no tiene reversa. Si se utiliza
de manera negligente el comando rm -r es muy peligroso.
Ejemplos
El usuario hogan ha estado trabajando bastante en un reporte, el cual tiene varios archivos que ha
organizado en subdirectorios bajo un directorio llamado report.
497
report/
|-- chapter01/
| |-- figures/
| | |-- image01.png
| | `-- image02.png
| |-- section01.html
| `-- section02.html
`-- chapter02/
|-- figures/
| |-- image01.png
| `-- image02.png
|-- section01.html
`-- section02.html
4 directories, 8 files
Está a punto de utilizar un corrector ortográfico para chequear y remplazar las palabras mal
escritas. Ya que esta es la primera vez que utiliza este corrector ortográfico, quiere hacer una copia
de seguridad de su trabajo antes de continuar. Primero trata de hacer una copia de seguridad con
el comando cp.
Al darse cuenta de su error añade la opción -r para decirle al comando cp que copie de modo
recursivo.
Ahora el contenido del directorio report es copiado de modo recursivo al directorio report.bak.
498
.
|-- report/
| |-- chapter01/
| | |-- figures/
| | | |-- image01.png
| | | `-- image02.png
| | |-- section01.html
| | `-- section02.html
| `-- chapter02/
| |-- figures/
| | |-- image01.png
| | `-- image02.png
| |-- section01.html
| `-- section02.html
`-- report.bak/
|-- chapter01/
| |-- figures/
| | |-- image01.png
| | `-- image02.png
| |-- section01.html
| `-- section02.html
`-- chapter02/
|-- figures/
| |-- image01.png
| `-- image02.png
|-- section01.html
`-- section02.html
10 directories, 16 files
Una vez que hogan haya usado el corrector ortográfico y que esté contento con los resultados,
quiere suprimir el directorio de copia de seguridad report.bak. Primero utiliza el comando rmdir.
Recuerde que rmdir sólo funciona en directorios vacíos así que en su lugar utiliza rm -r.
El usuario ventura está interesado en programar con el lenguage python. Descubrió scripts de
muestra en el directorio /usr/share/doc/pygtk2-1.99.14/examples/. Le gustaría jugar con los scripts
para poder probar nuevas ideas, pero no tiene permiso de escritura en los archivos. Decide hacer
una copia local de los scripts.
499
[ventura@station ventura]$ cp -r /usr/share/doc/pygtk2-1.99.16/examples/ .
[ventura@station ventura]$ ls -R examples/
examples/:
atk gl glade gobject ide neil pango pygtk-demo simple
examples/atk:
atk-demo.py
examples/gl:
cone.py dots.py gears.py README
examples/glade:
glade-demo.py README test.glade
examples/gobject:
properties.py signal.py
examples/ide:
break.xpm edit.py gtkdb.py next.xpm README step.xpm
browse.py edit.xpm gtkprof.py pyide.py return.xpm
...
Observe el uso del nombre de directorio . para referirse a "el directorio local". Cuando cp
recibe un directorio como destino (el último argumento) copia a ese directorio, preservando los
nombres de los archivos originales. En este caso, el directorio examples fue copiado al
directorio ..
El comando ls -R genera una lista recursiva de todo archivo en el directorio recién creado
example.
Ahora ventura tiene una copia a nivel local de los scripts python, lo que significa que los puede
modificar cuando quiera.
Ejercicios en línea
Administración de directorios Lab Exercise Objetivo: Listar, copiar, mover y suprimir directorios de
manera eficiente. Tiempo estimado: 20 minutos.
Especificaciones
1. Utilice el comando ls (con las opciones apropiadas) para obtener un listado recursivo,
incluyendo tamaños (-s) del contenido del directorio /usr/share/gdm. Redireccione la salida
del comando a un archivo en su directorio de inicio llamado lsgdm.txt (debido a propósitos
evaluativos es importante que especifique el directorio como una referencia absoluta, por
ejemplo, no share/gdm).
2. Haga un copia (recursiva) del directorio /usr/share/gdm en su directorio de inicio. El
directorio copiado también se debe llamar gdm.
3. Haga una segunda copia del directorio recién creado en su directorio de inicio. gdm,
llamado gdm.bak.
500
4. Desde su copia de seguridad, suprima (de modo recursivo) el subdirectorio
gdm.bak/themes/circles.
5. De nuevo desde su copia de seguridad, mueva el subdirectorio gdm.bak/themes/Bluecurve
a su directorio de inicio (el directorio todavía se debe llamar Bluecurve).
Limpieza
Los directorios creados son bastante grandes, así que si quiere conservar espacio de disco puede
borrarlos cuando haya terminado.
501
Nombres y comodines de archivos
Conceptos clave
Discussion
Nombres de archivo
Muchos sistemas operativos restringen el número y tipo de caracteres que se pueden utilizar al
nombrar archivos. En Linux, virtualmente cualquier caracter imprimible se puede utilizar en el
nombre de archivo y los nombres pueden ser casi de cualquier longitud.
Los nombres de archivos de Linux pueden tener hasta 255 caracteres, excluyendo cualquier
componente de directorio. Cuando se utiliza en un comando, un nombre de archivo absoluto o
relativo, incluyendo los componentes del directorio, pueden tener hasta de ¡4095 caracteres! Esto
permite que los nombres de archivo y directorios puedan ser bastante descriptivos.
Los nombres de archivos de Linux pueden contener cualquier caracter imprimible (y algunos que
no lo son) a excepción de la barra oblicua /. Esta barra no puede ser parte del nombre de archivo,
puesto que es el caracter utilizado para separar los componentes del nombre de un directorio en un
nombre relativo o completamente calificado. Como la mayoría de los caracteres "inusuales" son
meta-caracteres de shell, deben estar protegidos entre comillas para poderlos utilizar en un nombre
de archivo:
Como lo puede ver, se crearon cuatro archivos con nombres un poco extraños.
Warning
El ejemplo anterior es sólo a manera de ilustración. Muchos de los caracteres utilizados en
este ejemplo son meta-caracteres shell, cuyo significado aún no se ha discutido aquí. Debe
evitar utilizar signos de puntuación en los nombres de archivos, pues si los utiliza de manera
inapropiada puede producir resultados desastrosos.
La advertencia anterior no se debe olvidar. En general, los nombres de archivos deben estar
compuestos de caracteres alfabéticos y numéricos (A-Z, a-z, 0-9) y signos de puntuación ._-+~
502
(punto, guión bajo, guión, más, tilde). Normalmente, los nombres de archivos deben iniciar con un
caracter alfanumérico o con un punto (vea la siguiente sección sobre archivos ocultos). Aunque
encontrará nombres de archivos con espacios incrustados no se recomienda utilizarlos.
Hogan intenta crear un directorio llamado 'bad dir,' pero sin saber creó dos directorios, uno
llamado 'bad' y otro llamado 'dir'.
Después, Hogan trata de crear un archivo llamado 'this and that' con touch, pero en realidad
crea tres archivos llamados 'this', 'and', y'that'.
Ahora Hogan intenta mover el archivo que él cree que se llama 'this and that' al directorio que
el piensa que se llama 'bad dir', pero lo que hace es mover todos los cuatro 'directoriosthis',
'and', 'that', y 'bad' (tres archivos comunes y un directorio) al directorio dir.
Puesto que todos los comandos anteriores se ejecutaron "con éxito", sólo hasta este momento
Hogan se da cuenta de que algo ha salido mal.
Es obvio que, si Hogan hubiese encerrado entre comillas los nombres como se mostró en las notas
explicativas, las cosas hubiesen funcionado como él lo quería. Hecho que vale la pena recordar, ya
que encontrará nombres de archivos con espacios encrustados. En relación a esto, un nombre de
archivo que contiene espacios al principio y al final es legal, pero es muy difícil de identificar en un
listado de archivos.
Hogan finalmente decide evitar los espacios. Esta vez intenta crear un directorio llamado 'bad-
> dir' pero sin querer crea un directorio llamado 'bad-' y un archivo llamado 'dir' (¿por qué?).
Después Hogan crea un archivo llamado 'this' con touch. ¡Este paso lo hace bien!
Ahora Hogan trata de mover un archivo llamado 'this' al directorio que el piensa que se llama
'bad->dir,' pero en vez de lograr esto, mueve 'this' al directorio bad-, redireccionando la salida
(no hay ninguna) al archivo 'dir'.
503
De nuevo, sólo hasta ahora Hogan se da cuenta de que algo ha salido mal.
Como antes, si Hogan hubiese utilizado las comillas para encerrar los nombres de archivos, las
cosas habrían salido como él quería. Las comillas enmascaran una multitud de pecados, pero no
utilice esto como excusa para crear nombres de archivos inapropiados. Muchas de las tareas que
aún tenemos que aprender se hacen más fáciles si se utilizan nombres "normales" para los
archivos.
Archivos ocultos
Los nombres de archivos y directorios (recuerde un directorio es un tipo de archivo) que comienzan
por un punto son archivos "ocultos". Estos archivos no aparecen en los listados de directorio
producidos por ls a menos que se utilice la opción de comando especial -a (del inglés all) o a
menos que se especifique el punto inicial como parte del nombre. Se hace posible reducir la
aglomeración de elementos y la confusión manteniendo ciertos archivos" fuera de vista y de
consideración".
En la próxima sección aprenderemos a nombrar múltiples archivos por medio de una técnica
conocida como uso de "comodines". En general, los archivos ocultos tampoco aparecen en un
"comodín" a no ser que el punto inicial sea listado específicamente.
Aparte de ocultar el archivo, el punto inicial no tiene otra importancia y los archivos y directorios
ocultos se pueden utilizar como cualquiera de los otros.
"Comodines"
Con frecuencia es necesario emitir un comando que actúe en más de un archivo. Los comandos
como cp -r y rm -r funcionan en sub-árboles enteros de directorios, sin embargo, Linux cuenta con
una manera más flexible de identificar grupos de archivos. La shell de comando bash trata algunos
de sus meta-caracteres especiales como comodines. Cuando bash lee la línea de comando, la
shell realiza un proceso llamado expansión de meta-caracteres o expansión de comodines, lo cual
genera una lista de nombres de archivos que coinciden con el patrón descrito por la expresión del
comodín y luego pasa la lista generada al comando. Esto se conoce comúnmente como
"comodines de nombres de archivos."
504
Table 1. Comodines
Caracter Efecto
* coincide con cero o más caracteres (a excepción del punto inicial)
? coincide exactamente con un caracter (a excepción del punto inicial)
[...] coincide exactamente con un caracter de la lista o rango
[^...] coincide exactamente con un caracter no incluido en la lista o rango
El uso de * y ? es más bien sencillo. Los comodines de listas son un poco más complicados, pero
también bastante poderosos y útiles.
El comodín de parentesis representa una lista de caracteres individuales. Por lo tanto, [aeiou]
coincide con cualquier vocal. Un rango contiguo de caracteres se puede representar utilizando un
guión como en [a-z] para el alfabeto en minúsculas. Una ^ inicial, niega la lista de manera que
[^aeiou] sea cualquier caracter menos una vocal. Un guión "real" se puede representar escapando
los caracteres utilizando una barra invertida (\) (más adelante se abordará este tema). Por lo tanto,
la expresión [a\-z] coincide con a, z o un guión sólamente. Se pueden mezclar caracteres
individuales y rangos. El patrón [A-Za-z0-9._\-+~] coincide con cualquiera de los caracteres
"seguros" de nombres de archivos mencionados anteriormente en la gráfica 5-1.
Los comodines se pueden utilizar con cualquier comando que espera el nombre de un archivo. Por
ejemplo, el comando
asumiendo que el directorio de inicio de Bob contiene los archivos listados anteriormente.
505
[Nota técnica: muchos de los comandos se comportan de manera diferente cuando no aparecen
archivos en la lista, contrario a cuando uno o más archivos se dan como parte del comando.
Entonces, ¿qué sucede en dicho comando si se utiliza un patron de comodín de modo que el
listado de archivos esté vacío? En el caso especial donde la shell bash intenta expandir una
expresión de comodín y no coincide con nada, ésta deja la expresión como parte del comando.
Esto se ilustra a continuación:
[bob@station bob]$ rm
rm: too few arguments
Try `rm --help' for more information.
[bob@station bob]$ rm z*
rm: cannot lstat `z*': No such file or directory
En el primer rm, el comando vio cero nombres de archivos y falló presentando un mensaje de
error. En la segunda versión, la shell no pudo generar una lista de nombres del patrón z* y por lo
tanto la cadena z*se envió a rm como el nombre de archivo mismo. Como Bob no tiene un archivo
llamado z* en su directorio, el comando falló con un mensaje diferente].
Ejemplos
Alice estaba revisando recientemente el archivo de configuración del DNS (Servicio de Nombres de
Dominio), pero olvidó el nombre. Recuerda que el archivo terminaba en .conf. Con el fin de reducir
el número de archivos a tomar en consideración, utilizó los comodines para listar todos los archivos
en el directorio /etc terminados en .conf.
506
Cuando echa un vistazo a las bibliotecas estáticas instaladas en su sistema, encuentra cerca de
1000 archivos en el directorio /usr/lib. Para reducir el número de archivos a examinar trata de listar
todos los archivos terminados en a.
...
/usr/lib/mozilla:
plugins
/usr/lib/samba:
vfs
Muchas de las líneas de este listado largo han sido borradas, pero se han dejado las suficientes
para ilustrar el problema, el "comodín" de bob no fue lo suficientemente específico y capturó
también algunos de los directorios terminados en a. Refinando un poco más la lista obtiene lo que
quiere.
...
/usr/lib/libimlib-jpeg.a /usr/lib/libz.a
/usr/lib/libimlib-png.a /usr/lib/libzvt.a
/usr/lib/libimlib-ppm.a
Luego, bob sospecha que las bibliotecas utilizadas con más frecuencia tienen nombres cortos y
eficientes (tal vez descriptivos). Procede a listar todas las bibliotecas que tengan nombres de una,
dos o tres letras.
507
[bob@station bob]$ ls /usr/lib/lib?.a
/usr/lib/libc.a /usr/lib/libl.a /usr/lib/libz.a
/usr/lib/libg.a /usr/lib/libm.a
[bob@station bob]$ ls /usr/lib/lib??.a
/usr/lib/libdl.a /usr/lib/libgd.a /usr/lib/librt.a
/usr/lib/libfl.a /usr/lib/libmp.a
[bob@station bob]$ ls /usr/lib/lib???.a
/usr/lib/libacl.a /usr/lib/libgdk.a /usr/lib/libosp.a
/usr/lib/librle.a
/usr/lib/libanl.a /usr/lib/libgif.a /usr/lib/libpam.a
/usr/lib/librpm.a
/usr/lib/libapm.a /usr/lib/libgmp.a /usr/lib/libpbm.a
/usr/lib/libSDL.a
/usr/lib/libbfd.a /usr/lib/libgpm.a /usr/lib/libpci.a
/usr/lib/libssl.a
/usr/lib/libbsd.a /usr/lib/libgtk.a /usr/lib/libpgm.a
/usr/lib/libttf.a
/usr/lib/libefs.a /usr/lib/libIDL.a /usr/lib/libpng.a
/usr/lib/libusb.a
/usr/lib/libesd.a /usr/lib/libnsl.a /usr/lib/libpnm.a
/usr/lib/libxml.a
/usr/lib/libgal.a /usr/lib/libogg.a /usr/lib/libppm.a
/usr/lib/libzvt.a
¿Hay alguna forma fácil de utilizar los comodines para que bob pudiese haber listado las
bibliotecas con uno, dos o tres caracteres de nombres con una sola expresión?
La usuaria alice descubrió que los archivos que contienen las páginas man se encuentran
instalados en el directorio /usr/share/man en los subdirectorios relacionanados con los capítulos de
las páginas man.
Como usuaria regular del sistema, sabe que los capítulos que más le interesan son el 1, 5 y 7.
Utiliza una expresión con comodines para enumerar sólo el contenido de esos directorios.
...
groff.7.gz wireless.7.gz
groff_char.7.gz x25.7.gz
groff_diff.7.gz
508
Si alice hubiese estado interesada en todas las páginas man de los capítulos numerados, pero no
en los capítulos impares "n" podría haber utilizado la expresión de rango con comodines.
...
named-checkconf.8.gz zic.8.gz
named-checkzone.8.gz
/usr/share/man/man9:
Ejercicios en línea
Administración de archivos con comodines Lab Exercise Objetivo: Administrar archivos de modo
eficiente por medio del uso de comodines de archivo.Tiempo estimado: 20 minutos.
Especificaciones
Este laboratorio utilizará comodines de archivo para administrar un gran número de archivos que
tienen nombres vagamente estructurados. Todos los archivos se encuentran en el directorio
/usr/share/tcl8.4/encoding.
Si ha realizado el ejercicio correctamente, debe tener los seis directorios con los siguientes
archivos.
509
[bob@station bob]$ ls *
cp_even:
cp1250.enc cp1256.enc cp852.enc cp864.enc cp932.enc
cp1252.enc cp1258.enc cp860.enc cp866.enc cp936.enc
cp1254.enc cp850.enc cp862.enc cp874.enc cp950.enc
cp_mid:
cp850.enc cp857.enc cp862.enc cp865.enc cp874.enc cp949.enc
cp852.enc cp860.enc cp863.enc cp866.enc cp932.enc cp950.enc
cp855.enc cp861.enc cp864.enc cp869.enc cp936.enc
cp_thousand:
cp1250.enc cp1252.enc cp1254.enc cp1256.enc cp1258.enc
cp1251.enc cp1253.enc cp1255.enc cp1257.enc
iso_mid:
iso8859-3.enc iso8859-5.enc iso8859-7.enc
iso8859-4.enc iso8859-6.enc iso8859-8.enc
mac:
macCentEuro.enc macDingbats.enc macJapan.enc macThai.enc
macCroatian.enc macGreek.enc macRoman.enc macTurkish.enc
macCyrillic.enc macIceland.enc macRomania.enc macUkraine.enc
xxxn:
big5.enc iso8859-13.enc iso8859-2.enc iso8859-7.enc jis0212.enc
iso2022.enc iso8859-14.enc iso8859-3.enc iso8859-8.enc koi8-r.enc
iso2022-jp.enc iso8859-15.enc iso8859-4.enc iso8859-9.enc koi8-u.enc
iso2022-kr.enc iso8859-16.enc iso8859-5.enc jis0201.enc ksc5601.enc
iso8859-10.enc iso8859-1.enc iso8859-6.enc jis0208.enc
sugerencias
El siguiente comando copiaría los archivos que coinciden con el primer criterio (asumiendo que el
directorio de trabajo actual es el directorio de inicio de Bob).
510
Examen de archivos
Conceptos clave
Discussion
Ver archivos
Linux ofrece varios comandos para examinar archivos y su contenido. Esta lección aborda algunas
de las herramientas más utilizadas.
El comando file
El contenido de cualquier archivo dado puede ser ASCII (texto plano, HTML, scripts de shell,
código fuente del programa, etc.) o binario (un ejecutable compilado, un archivo, comprimido,
audio, etc.).
Los comandos analizados en este capítulo son sólo para uso en archivos ASCII, el intentar usarlos
con archivos binarios puede generar problemas un poco molestos (como pantallas llenas de
caracteres extraños) o hasta problemas mayores (bloqueando la terminal). Esto se debe a que los
archivos binarios pueden contener códigos binarios arbitrarios y algunos de estos códigos tienen
un significado especial cuando se (mal )interpretan como texto ASCII. Por lo tanto, es una buena
idea revisar el tipo de archivo de cualquier archivo que usted no reconozca utilizando file antes de
intentar ver el archivo con otra de las herramientas que se muestran aquí.
Prueba FILE(s) para determinar el tipo de archivo y muestra los resultados en la salida estándar.
511
[nero@station nero]$ file logo.jpeg symphony.mp3 archive.tgz
logo.png: PNG image data, 387 x 69, 8-bit grayscale, non-
interlaced
symphony.mp3: MP3, 128 bits, 44.1 kHz, JStereo
archive.tgz: gzip compressed data, deflated, last modified: Thu
Mar 20 21:27:27 2003, os: Unix
El comando cat
Este comando se introdujo por primera vez en el capítulo 3 de este cuaderno. Aquí le mostramos
algunas de sus opciones.
Opción Efecto
-A Muestra todos los caracteres incluyendo los caracteres de control y los de no impresión.
-s " Apiña" múltiples líneas adyacentes en blanco en una sóla línea en blanco
-n Numera las líneas de la salida
El comando cat, cuando se utiliza para ver archivos, simplemente muestra todo el contenido de
una sola vez. Los archivos largos pasan por la pantalla de manera muy rápida haciendo que cat
sea el comando más apropiado para aquellos archivos con menos de una pantalla de texto.
Tanto more como less están diseñados para ver archivos de texto en la pantalla. Su uso es muy
similar aunque el comando less es un poco más moderno y tiene unas pocas características extras
tales como el responder de manera correcta a [PgArriba], [PgAbajo] y a las flechas de navegación.
Después de todo,less es more.
Es bien importante familiarizarse con el comando less, ya que otras herramientas (como man) lo
utilizan en segundo plano para brindar funciones de paginador.
Muestra el/los archivo(s)FILE(s) en la salida estándar y una pantalla a la vez bajo el control del
teclado.
Opción Acción
-c Limpia la pantalla y redibuja en vez de desplazarse
-s "Apiña" múltiples líneas adyacentes en blanco en una sóla línea en blanco
Muestra el/los archivo(s)FILE(s) en la salida estándar y una pantalla a la vez bajo el control del
teclado.
512
Opción Acción
-c Limpia la pantalla y redibuja en vez de desplazarse
-r Muestra los caracteres de control básico
-s "Apiña" múltiples líneas adyacentes en blanco en una sóla línea en blanco
Una de las características del paginador less es que depende de un concepto estándar de Unix
llamado tuberías. Aunque las tuberías se discuten más adelante esta característica de less es
bastante útil y sencilla de utilizar así que amerita presentarla ahora. Una tubería actúa como un
redireccionamiento en donde la salida de un comando es redireccionado a un lugar distinto de la
terminal. Con la redirección (usando >) la salida se redirecciona a un archivo específico. Cuando se
utiliza una tubería la salida de un comando es redireccionada como entrada de otro comando. La
shell bash usa el caracter | (suele encontrarse encima de la tecla RETURN) para construir
tuberías.
Al ejecutar un comando que produce bastante salida, ésta se puede poner en una tubería
usandoless. En vez de ser botada a una terminal, la salida se puede navegar como si fuese un
archivo, subiendo y bajando de página y haciendo búsquedas. Cuando termine salga de less y la
salida desaparecerá.
El usuario elvis está utilizando el comando ps aux para ver una tabla con todos los procesos que
están ejecutándose en la máquina. Como espera que la salida sea más bien larga, decide
entonces poner una tubería del comando al navegador less.
513
Ahora él puede utilizar la mismas secuencia que utiliza al navegar un archivo (o las páginas man)
para hojear las salidas de los comandos ps:ESPACIO para avanzar, b para retroceder,
/textRETORNO para buscar el texto text, y q para salir.
El comando head
Algunas veces todo lo que se necesita al examinar un archivo es ver las primeras líneas del
archivo. El comando head nos permite hacer esto.
Opción Efecto
-num, -n Imprime las primeras num líneas (por defecto es 10).
num
-q Suprime encabezados que dan nombres de archivo
En el siguiente ejemplo elvis examinará las primeras 10 líneas y luego las primeras 5 líneas del
archivo /etc/group.
514
[elvis@station elvis]$ head -5 /etc/rc.d/init.d/*
==> /etc/rc.d/init.d/aep1000 <==
#!/bin/sh
#
# Tags
# chkconfig: - 30 70
# description: load and unload AEP1000/AEP2000 coprocessor driver
...
Así como con el paginador less de arriba, la salida de comandos largos se puede truncar al
establecer una tuería en el comando head.
El comando tail
Para complementar head, el comando tail muestra las últimas 10 líneas de cada FILE a la salida
estándar.
515
Opción Efecto
-num, -n Muestra las últimas num líneas (por defecto es 10).
num
-q Suprime encabezados que dan nombres de archivo
-f Mantiene el archivo abierto y escribe las nuevas líneas como añadidas
En el siguiente ejemplo, elvis escribe las últimas 10 líneas y después las ultimas 5 del archivo /etc/
group.
El comando tail tiene otra opción bastante útil: la opción -f (follow). Con esta opción tail mostrará
las últimas líneas del archivo y luego "espera" y continua presentando cualquier nueva línea al ser
añadida al archivo. Frecuentemente, se utiliza para monitorear archivos de registro en tiempo real.
Una vez inicie con esta opción, el intérprete de comandos no retorna. En su lugar, tail -f se
mantiene activa y continuará presentando las nuevas líneas hasta que se presione CTRL-C.
A title
Ejemplos
Al explorar la configuración del sistema de impresión cups, prince se encontró con los siguientes
archivos en el directorio /usr/share/cups/banners.
Como no está seguro de qué tipo de archivos son, trata entonces de identificarlos con el comando
file.
516
[prince@station banners]$ cd /usr/share/cups/banners/
[prince@station banners]$ file *
classified: PostScript document text conforming at level 3.0
confidential: PostScript document text conforming at level 3.0
secret: PostScript document text conforming at level 3.0
standard: PostScript document text conforming at level 3.0
topsecret: PostScript document text conforming at level 3.0
unclassified: PostScript document text conforming at level 3.0
El comando file revela que éstos son documentos PostScript enviados a la impresora como
pancartas.
El usuario elvis acaba de descargar algunas imágenes del álbum de fotos del sitio web de su amigo
y las guardó en un directorio llamado pics.
Observa las extensiones de cuatro de los archivos y parecen estar en formato PNG, mientras que
dos de ellas parecen tener formato JPEG. Al parecerle extraño, confirma el tipo de archivos
ejecutando el comando file.
Los últimos dos archivos están en formato PNG como los otros cuatro. Aparentemente, los dos
últimos fueron nombrados con una extensión equivocada.
La usuaria blondie recientemente aprendió que todos los archivos del directorio /etc/profile.d
terminados en .sh se encuentran incluidos en su configuración de shell bash cada vez que inicia
sesión. Interesada en saber lo que contienen los archivos decide hojear las primeras líneas de
cada archivo con el siguiente comando.
517
[blondie@station blondie]$ head /etc/profile.d/*.sh
sourced=0
for langfile in /etc/sysconfig/i18n $HOME/.i18n ; do
[ -f $langfile ] && . $langfile && sourced=1
done
if [ -n "$GDM_LANG" ]; then
sourced=1
LANG="$GDM_LANG"
...
Combinación de archivos múltiples en un sólo archivo con head
La usuaria madonna está aprendiendo sobre PAM, los módulos de autenticación conectables de
Linux. Acaba de descubrir el directorio /usr/share/doc/pam-0.75/txts, el cual contiene un gran
número de archivos README.
En vez de examinar cada archivo individualmente ella quisiera combinarlos en un sólo archivo para
poderlo navegar fácilmente. Sabe que puede utilizar el comando cat y redireccionar la salida al
archivo, pero ya no sabría los nombres de archivos asociados con cada uno de estos archivos. En
su lugar, decide utilizar el comando head, dándole un número absurdo de líneas a seleccionar. De
esa manera, podrá navegar el contenido de los archivos con un aviso identificador otorgando el
nombre de archivo.
518
[madonna@station txts]$ head -99999 README* > /tmp/pam_READMEs.txt
[madonna@station txts]$ less /tmp/pam_READMEs.txt
==> README <==
$Id: 010_text.dbk,v 1.1.1.1 2003/08/11 13:18:31 bowe Exp $
En Red Hat Enterprise Linux, los eventos del sistema se registran en archivos de texto que se
encuentran en el directorio /var/log tales como /var/log/messages (para eventos del sistema en
general) y /var/log/secure (para aquellos eventos que incluyen información importante). Cuando los
eventos ocurren se añaden nuevas líneas a estos archivos en tiempo real.
Suponga que un administrador de sistemas quisiera observar ambos archivos de registro y ver la
nueva información tan pronto como llega. Ella utiliza el comando tail -f para seguir el final de
ambos archivos. El comando tail inmediatamente presenta las últimas 10 líneas de ambos
archivos, decoradas por el nombre de archivo.
519
[root@station root]# cd /var/log
[root@station log]# tail -f messages secure
En este punto, el comando tail sigue ejecutándose, pero la salida hace una pausa hasta que ocurre
un nuevo evento en el sistema, el cual se registra en uno de los archivos. Después el comando tail
muestra las nuevas lineas añadidas decoradas con el nombre de archivo del archivo pertinente.
Ejercicios en línea
Navegar archivos de texto Lab Exercise Objetivo: Examinar archivos usando varias utilidades
para navegar. Tiempo estimado: 15 minutos.
Especificaciones
En este ejercicio necesitará tres terminales (ya sean consolas virtuales o terminales dentro del
entorno gráfico X) cada una utilizando su cuenta primaria.
520
2. Mientras esté en la primera terminal haga un listado recursivo de todos los archivos con el
comando ls -R / y atrape la salida (utilizando una tubería) con el paginador less. Use los
comandos básicos del paginador tales como ESPACIO y b para navegar la salida. Explore
otros comandos del paginador utilizando el comando h para abrir una ventana de ayuda.
Cuando haya terminado, NO salga del paginador less, vaya a una nueva terminal para
realizar el siguiente paso.
3. En la segunda terminal, use el comando head para ver las primeras 5 líneas de todos los
archivos en el directorio /etc/sysconfig cuyo nombre empieza por system- al archivo
confheaders.txt en su directorio de inicio. Utilice la opción apropiada para suprimir los
encabezados con los nombres de archivos que head imprime por defecto.
4. Al seguir en la segunda terminal, ejecute el comando vmstat 1. Este comando traza las
estadísticas de la memoria y la CPU de su máquina generando una línea una vez por
segundo. Cuando haya visto lo suficiente, utilice la secuencia CTRL-C para matar el
comando.
5. NO pare este comando, déjelo ejecutando. Vaya a una nueva terminal para realizar el
siguiente paso.
6. En una tercera terminal siga el creciente archivo vmstat.out con el comando tail -f. NO
pare el comando tail hasta no haber confirmado el siguiente ejercicio.
Limpieza
Después de completar este ejercicio salga del paginador less con el comando q y termine los
comandos vmstat y tail con la secuencia de controlCTRL-C.
521
Modificación de archivos
Conceptos clave
Discussion
Una de las maneras en que Linux alcanza su alto nivel de flexibilidad es por medio de la robustez
de su configuración. Usualmente la información sobre la configuración se encuentra almacenada
en archivos de texto ASCII. Con frecuencia la administración de sistemas involucra la actualización
o corrección de estos archivos de configuración. La herramienta para lograr esto es un editor de
texto.
Un procesador de palabras sería una opción apropiada para escribir una carta, un memo, un
boletín, un folleto o cualquier documento en donde la presentación visual sea controlada por el
software de edición.
Un editor de texto es la opción apropiada para crear o modificar archivos de configuración, código
fuentes de programas, documentación del sistema o cualquier documento (así como documentos
HTML) en donde la presentación visual es controlada por el software (tal como un navegador de
web) y no por el software de edición. Debido a que este curso se enfoca en la administración de
sistemas Linux, los editores de texto serán nuestra herramienta en la mayoría de los casos.
Linux viene junto con un juego completo de editores de texto, cada uno con sus fortalezas y
debilidades. Linux también incluye procesadores de palabra para la creación de documentos como
parte de productos tales como OpenOffice.
Como todos los editores de texto trabajan en archivos de texto sencillos, puede escoger el que
quiera sin problemas de compatibilidad entre los productos. Normalmente se escoge una opción
con base en la disponibilidad, facilidad de uso, familiaridad y características especiales. Por
ejemplo, algunos editores facilitan la generación de código de programas formateados de manera
correcta haciendo que la programación sea mucho más fácil y rápida. Este capítulo presenta dos
editores fáciles de utilizar nano y gedit. El editor de texto más popular en los sistemas Linux es vi
522
y también es el más robusto y el más complicado. La complejidad de este editor hace difícil
abordarlo en un curso introductorio.
nano
nano es un editor de texto simple que presenta una pantalla completa. Los comandos se presentan
al final de la pantalla y se proporciona ayuda de acuerdo con el contexto. Al escribir los caracteres
estos se insertan de manera inmediata en el texto.
Uso:
Comando Función
^G Ayuda - abre una pequeña ventana de ayuda
^X Salir - sale (y opcionalmente guarda el archivo)
^O Escribir - guarda el archivo
^J Justificar
^R Leer el archivo - e insertar en la posición del cursor
^W Dónde está - búsqueda de texto
^Y Página anterior -retrocede una página
^V Próxima página - adelanta una página
^K Cortar texto - corta una línea a la vez
^U Deshace el corte de texto - inserta el último bloque de texto cortado
^C Posición del cursor- identifica el número de línea y de columna
^T Corrector ortográfico - empieza a corregir la ortografía
Opción Función
-w desactiva el ajuste de texto
-v "ver" el archivo en modo de sólo-lectura
Los archivos de configuración pueden sufrir daños debido a cortes de línea indebidos, así que con
frecuencia se inicianano con la opción-w para editar estos archivos.
gedit
gedit es un editor gráfico de texto disponible para el entorno de X-window. Se puede acceder a él
entrando gedit en el intérprete de comandos de una terminal o seleccionando Accesorios -> Editor
de texto del menú de GNOME. Proporciona una interfaz familiar de documentos para crear y
modificar archivos de texto e iconos de barras de herramientas para acceder a características tales
523
como búsqueda y remplazo, cortar-copiar -pegar, e imprimir. Esta ventana cuenta con pestañas
que permiten abrir más de un documento a la vez. También soporta una interfaz estándar para
interactuar con el sistema de archivos.
Ejercicios en línea
Editores de texto Lab Exercise Objetivo: Editores de texto Estimated Time: 10 mins.
Especificaciones
El editor nano
1. En su directorio de inicio cree una copia del archivo /etc/services llamado services.nano
2. Abra el archivo services.nano utilizando el editor de textos nano.
3. Al usar las secuencias de control especificadas al final de la pantalla, busque y borre todas
las ocurrencias del caracter +. Mantenga los espacios de las columnas y guarde su archivo
como services.noplus.
4. Continuando en la misma sesión de edición mueva su cursor a la línea 140. La
combinación CTRL-C le informará el número de línea actual (observe que CTRL-C, el
comando que usualmente termina un proceso, ha sido sobrescrito por el editor nano y
tiene un nuevo comportamiento). Borre esa línea y la siguiente. Guarde su archivo como
services.nonext.
5. Cierre el editor nano.
524
El editor gedit
1. En su directorio de inicio cree una copia del archivo /etc/services llamado services.gedit
2. Abra el archivo services.gedit utilizando el editor de texto gedit.
3. Mueva su cursor a la línea número 100 (el explorar un poco el menú de gedit le puede
simplificar esta tarea). Borre toda la línea y las dos siguientes. Guarde su archivo como
services.notsmux.
4. Remplace toda ocurrencia de la letra tcp con udp. Realice la búsqueda y remplace
teniendo en cuenta mayúsculas y minúsculas (por ejemplo, no remplace TCP). Guarde su
archivo como services.notcp.
5. Cierre el editor gedit.
525
Supplements
Escritura avanzada de shell
Conceptos clave
• Linux utiliza el mecanismo de scripts, en donde los archivos de scripts de texto pueden ser
ejecutados por un intérprete especificado en la línea inicial.
• Dentro de un script bash, los argumentos provistos al invocar un script están disponibles
como parámetros posicionales (por ejemplo, las variables $1, $2, ...).
• El comando incorporado read se puede utilizar para leer la entrada desde la "entrada
estándar" del teclado.
• La shell utiliza una sintaxis if ... then ... [else ...] fi para implementar ramas condicionales.
• El comando test suele utilizarse como comando condicional en ramas if ... then.
• La shell bash utiliza una sintaxis for ... in ... do ... done para implementar bucles.
Discussion
Escritura de shell
En capítulos anteriores a este cuaderno discutimos la creación de scripts simples de shell. Estos
scripts hacían algo más que ejecutar una serie de comandos, opcionalmente aceptando la salida
del usuario para definir variables.
Sin embargo, los scripts de shell son capaces de mucho más. Este capítulo agregará algunas
herramientas valiosas, permitiéndole a sus scripts tomar decisiones si/entonces/otro, en inglés
if/then/else, y retroalimentar una serie de acciones de modo indefinido.
Al programar, las ramas le permiten a los programas escoger entre una o dos (o más) rutas
alternas de ejecución. La shell bash, al igual que la mayoría de los lenguajes de programación,
utiliza la palabra si, en inglés if, para significar una rama. Más formalmente, bash utiliza la siguiente
sintaxis.
if condición
then
comando(s)
...
fi
526
if condición
then
comando(s)
...
else
comando(s)
...
fi
Al utilizar esta sintaxis, los retornos de carro son importantes (por ejemplo, el if y then deben
presentarse en líneas separadas), pero las sangrías no lo son.
¿Qué espera bash como condición? A diferencia de la mayoría de los lenguajes de programación,
bash no tiene sintaxis interna para hacer comparaciones (¿tales como $ A == apple, o $B >25). En
su lugar, bash se concentra en la razón de su diseño inicial: la ejecución de comandos. Cualquier
comando se puede utilizar para la condición. La shell bash ejecutará el comando y examinará su
valor de retorno. Si el comando tiene "éxito"(devuelve un valor de retorno de 0), la primera estrofa
de comandos se ejecutará. Si el comando fracasa (devuelve un valor de retorno no igual a cero), la
segunda estrofa de comandos se ejecutará (si existe).
[elvis@station elvis]$ ls
example.sh shut
[elvis@station elvis]$ cat shut
#!/bin/bash
# the first argument should be the name of the file to shut.
if ls $1
then
chmod 600 $1
else
echo "The file $1 does not exist."
fi
[elvis@station elvis]$ ./shut example.sh
example.sh
[elvis@station elvis]$ ./shut foo
ls: foo: No such file or directory
The file foo does not exist.
En el primer caso, el comando ls tiene "éxito" (porque el archivo example.sh existe, el valor de
retorno del comando ls es 0). Como resultado, la primera estrofa de la cláusula if ... then ... else ...
fi se ejecuta. En el segundo caso, el archivo foo no existe, por lo tanto la segunda estrofa (otro) de
la cláusula se ejecutó.
527
El comando test
El ejemplo anterior es bastante raro. El comando ls se ha forzado a realizar una labor para la cual
no está diseñado: probar si existe un archivo. Aunque puede hacer esto, los mensajes que imprime
distraen la atención. Si el archivo especificado existe, su nombre se imprime en la pantalla. Si el
archivo no existe, entonces un mensaje de error se imprimirá en pantalla. Si solo hubiera un
comando que comprobara la existencia del archivo y retornara el código de retorno apropiado, sin
emitir otros mensajes...
Lo hay. El comando se llama test. El comando test fue diseñado específicamente para este
propósito: para ser un comando condicional en frases bashif ... then. Más específicamente, el
comando test está diseñado para comparar cadenas de texto, números enteros y atributos de
archivo. Nunca genera salida, en cambio, se comunica mediante su valor de retorno. El comando
test retorna 0 si la expresión que evalúa es verdadera y un valor de no cero si no lo es.
if test -e $1
then
chmod 600 $1
else
echo "The file $1 does not exist."
fi
[elvis@station elvis]$ ./shut example.sh
[elvis@station elvis]$ ./shut foo
The file foo does not exist.
Observe que el comando test examina la existencia de un archivo, pero no genera mensajes para
distraer la atención del usuario.
El siguiente cuadro lista algunas de las opciones más comunes para examinar los atributos de los
archivos.
Expresión Condición
-d ARCHIVO El ARCHIVO existe y es un directorio.
-e ARCHIVO El ARCHIVO existe
-f ARCHIVO El ARCHIVO existe y es un archivo regular.
-r ARCHIVO El ARCHIVO existe y es leíble.
-w ARCHIVO El ARCHIVO existe y es escribible.
-x ARCHIVO El ARCHIVO existe y es ejecutable.
FILE1 -nt El FILE1 en más reciente que ARCHIVO2.
ARCHIVO2
528
Expresión Condición
[-n] CADENA DE la longitud de CADENA DE TEXTO es mayor que cero.
TEXTO
-z CADENA DE TEXTO la longitud de CADENA DE TEXTO es cero.
CADENA1 = CADENA2 CADENA1 y CADENA2 son iguales.
CADENA1 != CADENA2 CADENA1 y CADENA2 no son iguales.
Por último, el siguiente cuadro lista las expresiones que permiten al comando test utilizar una
lógica compuesta.
Expresión Condición
EXPRESIÓN1 -a Tanto EXPRESIÓN1 como EXPRESIÓN2 son verdaderas.
EXPRESIÓN2
EXPRESIÓN1 -o EXPRESIÓN1 o EXPRESIÓN2 es cierta.
EXPRESIÓN2
! EXPRESIÓN EXPRESIÓN es falsa.
Estos cuadros ofrecen al estudiante una serie de expresiones útiles. Para obtener una lista
completa, consulte la página de manual test(1).
Como el comando test es tan utilizado en scripts bash se ha desarrollado una sintaxis más corta.
Las siguientes dos expresiones son equivalentes.
test expresión
[ expresión ]
if [ -e $1 ]
then
chmod 600 $1
else
echo "The file $1 does not exist."
fi
529
Al utilizar la sintaxis alterna, se debe tener cuidado de incluir un espacio después de abrir el
paréntesis y antes de cerrarlo.[1] Por ejemplo, las siguientes dos construcciones del comando test
están erradas.
[-e foo.sh ]
[ -e foo.sh]
[-e foo.sh]
Los bucles son quizás la estructura de programación más útil para automatizar trabajos
convencionales. Los bucles permiten la repetición de una serie de comandos, usualmente con
leves variaciones en cada iteración. Estas variaciones se suelen ejecutar mediante una variable
conocida como un iterator. Para cada iteración del bucle, la variable toma un valor diferente. Por
ejemplo, elvis pudo utilizar el siguiente guión para afirmar su afecto por su colección de mascotas
domésticas.
En este script, la variable de shell PET se utiliza como iterador. Con cada iteración del bucle, la
variable adquiere un valor diferente.
Más formalmente los bucles for ... in ... do ... done en bash utilizan la siguiente sintaxis.
530
Para cada repetición del bucle, la variable iterator evaluará las palabras individuales en la
expresión lista
Para un ejemplo más práctico, revisitaremos el guión de elvis shut. El usuario elvis desearía
modificar su guión, con el fin de poder especificar archivos múltiples en la línea de comandos. Para
implementar este cambio, esencialmente toma su guión anterior y lo delimita dentro de un bucle for
... in .. do ... done. En lugar de utilizar el primer parámetro posicional ($1) directamente, elvis utiliza
un iterador a través de todos los argumentos provistos en la línea de comandos.
for FILE in $*
do
if [ -e $FILE ]
then
chmod 600 $FILE
else
echo "The file $FILE does not exist."
fi
done
A continuación, elvis utiliza el guión para modificar los permisos en los archivos example.sh y nice.
[elvis@station elvis]$ ls -l
total 12
-rwxr-xr-x 1 elvis elvis 212 Sep 3 10:56 example.sh
-rwxr-xr-x 1 elvis elvis 77 Sep 4 12:16 nice
-rwxrwxr-x 1 elvis elvis 188 Sep 4 12:31 shut
[elvis@station elvis]$ ./shut example.sh biz nice baz
The file biz does not exist.
The file baz does not exist.
[elvis@station elvis]$ ls -l
total 12
-rw------- 1 elvis elvis 212 Sep 3 10:56 example.sh
-rw------- 1 elvis elvis 77 Sep 4 12:16 nice
-rwxrwxr-x 1 elvis elvis 188 Sep 4 12:31 shut
Observe el uso de la variable $* para generar la lista. El siguiente cuadro sugiere otros trucos del
oficio.
531
Ejemplos
El usuario elvis se da cuenta que a menudo está "tarring up" (archivando) directorios que no está
utilizando. Decide crear un guión llamado pack, el cual le ayudará a archivar directorios más
rápidamente.
El script pack espera que uno o más directorios sean listados como argumentos. Para cada
directorio, el script creará un archivo llamado como el directorio con la extensión .tgz agregada.
Sólo si la creación del archivo tiene éxito, el script eliminará el directorio original.
Como elvis considera detenidamente los directorios que los usuarios pueden especificar, se da
cuenta que los directorios . y .. pueden causar problemas (¿por qué?), entonces les agrega una
exclusión.
if [ -d $DIR ]
then
532
[elvis@station elvis]$ mkdir test{1,2}
[elvis@station elvis]$ touch test{1,2}/{one,two,three,four}
[elvis@station elvis]$ ls -R
.:
pack test1 test2
./test1:
four one three two
./test2:
four one three two
[elvis@station elvis]$ ./pack test1 test2
test1/
test1/one
test1/two
test1/three
test1/four
test2/
test2/one
test2/two
test2/three
test2/four
[elvis@station elvis]$ ls -R
.:
pack test1.tgz test2.tgz
Los directorios de prueba se han "empacado".
Ejercicios en línea Lab Exercise Objetivo: Utilizar scripts shell para automatizar la rotación de
imágenes.Estimated Time: 30 mins.
Especificaciones
Crear un script llamado rotate_cw que sirva para rotar imágenes 90 grados. Para realizar la
rotación, debería utilizar el comando convert (analice la página de manual convert(1) y preste
mucha atención a la opción rotate). A continuación presentamos un ejemplo de uso del comando
convert para rotar una imagen.
El script debe esperar como argumentos múltiples nombres de archivo de las imágenes que van a
ser rotadas. Debe asumir que los nombres de archivo no contienen componentes de directorio (por
ejemplo, se referirán a archivos en el directorio actual). El guión debe generar un nuevo archivo de
la imagen rotada y si la nueva imagen se genera correctamente, remplace la imagen original con la
imagen rotada (dando la apariencia de rotar imágenes "en su lugar".
533
Un script bash ejecutable llamado ~/rotate_cw, el cual rotará imágenes en el directorio local
cuyos nombres de archivo (sin componentes de directorio) pasan como argumentos.
content_view let_
534
Codificación de caracteres e internacionalización
Conceptos clave
• When storing text, computers transform characters into a numeric representation. This
process is referred to as encoding the text.
• In order to accommodate the demands of a variety of languages, several different encoding
techniques have been developed. These techniques are represented by a variety of
character sets.
• La técnica más sofisticada de codificación se conoce como el Conjunto Universal de
Caracteres (UCS)
• La técnica de codificación en Linux de Red Hat Enterprise se conoce como UTF-8, la cual
permite la flexibilidad de Unicode y a su vez retiene la compatibilidad de ASCII.
• La variable de entorno LANG se utiliza para especificar un lenguaje preferido del usuario y
la codificación de caracter.
Archivo
Codificación de texto
Perhaps the most common type of data which computers are asked to store is text. As computers
have developed, a variety of techniques for encoding text have been developed, from the simple in
concept (which could encode only the Latin alphabet used in Western languages) to complicated
but powerful techniques that attempt to encode all forms of human written communication, even
attempting to include historical languages such as Egyptian hieroglyphics. The following sections
discuss many of the encoding techniques commonly used in Red Hat Enterprise Linux.
Internacionalización (i18n)
As this Workbook continues to discuss many tools and techniques for searching, sorting, and
manipulating text, the topic of internationalization cannot be avoided. In the open source
community, internationalization is often abbreviated as i18n, a shorthand for saying "i-n with 18
letters in between". Applications which have been internationalized take into account different
languages. In the Linux (and Unix) community, most applications look for the LANG environment
variable to determine which language to use.
At the simplest, this implies that programs will emit messages in the user's native language.
More subtly, the choice of a particular language has implications for sorting orders, numeric
formats, text encoding, and other issues.
535
El Administrador de paquetes RPM
Conceptos clave
Discussion
Por lo general, los guiones distribuídos con código abierto realizan cada uno de estos pasos más
fácilmente, pero incluso ellos no tratan dos problemas fundamentales. El primero es el problema de
dependencia. A menudo, los productos de fuente abierta reutilizan código distribuido en forma de
una biblioteca. Si la biblioteca apropiada no está instalada aún en el sistema, la aplicación que
depende de ésta no servirá. El segundo problema fundamental es el mantenimiento. ¿Qué sucede
cuando, después de seis meses lanzan una nueva versión del producto o alguien decide no querer
más un producto en particular? Se necesitaría rastrear y quitar o remplazar los archivos
individuales del producto.
RPM está diseñado para ayudar a resolver esos dos problemas fundamentales.
Cuando la gente habla de RPM se refiere a tres componentes colectivamente: la base de datos
RPM, el ejecutable rpm y los archivos de paquete.
La base de datos RPM es el centro del producto, proporciona la respuesta a los dos problemas
antes mencionados. Cada vez que el programa es instalado por RPM, se crean las entradas de
base de datos que representan cada archivo instalado. Debido a la base de datos, los archivos se
pueden quitar fácilmente desde el sistema más tarde.
536
Además, la base de datos mantiene una lista de dependencias requerida y provista por varios
paquetes. Al instalar una aplicación que requiere una biblioteca, por ejemplo, la biblioteca se puede
listar como dependencia específica y la base de datos puede responder de modo inequívoco por la
presencia (o ausencia) de la biblioteca.
La base de datos reside en el directorio /var/lib/rpm, pero aparte de saber que existe, los usuarios
estándar (o incluso el administrador) poco necesitarán acceder al directorio directamente.
El ejecutable rpm
Los usuarios interactúan con la base de datos RPM a través del comando rpm. El ejecutable es
utilizado por administradores para instalar, modernizar o quitar paquetes de programas y por el
usuario para contestar preguntas acerca de los paquetes instalados o verificar su integridad.
Examinaremos las solicitudes de RPM en detalle más adelante.
Archivos de paquete
Los archivos de paquete son el medio por el cual se distribuyen los programas. Los archivos de
paquete suelen nombrarse mediante la siguiente convención.
nombre-versión-publicación.archivo.rpm
Por ejemplo, la primera publicación del archivo de paquete para versión 4.0.7 de la aplicación zsh
de código abierto compilado para la arquitectura Intel x86 (y compatible) se llamaría
convencionalmente zsh-4.0.7-1.i386.rpm.
Los archivos de paquete son esencialmente archivos tar (aunque más de cerca parecen archivos
cpio menos familiares) combinados con la información de encabezado, la cual nombra versiones y
dependencias de estados para el paquete. Cuando la gente se refiere a la distribución de Red Hat,
generalmente se refiere a la colección de archivos de paquete RPM que componen el programa
instalado en una máquina.
Cuando se invoca con -q como su primera opción, el comando rpm realizará peticiones a la base
de datos RPM (o algunas veces archivos de paquete RPM directamente).
Cuando se presenta por primera vez a rpm, la sintaxis asociada con peticiones puede ser un poco
abrumadora. Ayuda a pensar que cada petición consta de dos preguntas: (1)¿Qué paquetes estoy
solicitando? (2)¿Qué pregunta estoy haciendo? Cada una de las opciones relacionadas con
peticiones del comando rpm entra en una de estas dos categorías.
Table 1. Opciones para realizar peticiones RPM con el fin de especificar paquetes
Opción Especificaciones
-a todos los paquetes instalados
paquete- el paquete nombre
nombre
-f filename el paquete propietario del archivo filename
537
-p paquete- solicitud del archivo de paquete paquete-archivo-nombre directamente. Esta
archivo- opción es fundamentalmente diferente, pues todas las otras opciones realizan
nombre una petición a la base de datos RPM de paquetes instalados.
Opción Especificaciones
(por defecto) nombre del paquete y versión
-i encabezado de información del paquete
-l lista de archivos pertenecientes al paquete
--queryformat lista información especificada en cadena de texto de formato str
str
Al escoger una opción desde el primer cuadro y cero o más opciones desde el segundo cuadro, los
usuarios pueden formular preguntas específicas para la base de datos RPM.
Ejemplos de peticiones
Peticiones generales
Por ejemplo, la opción -a realiza una solicitud en todos los paquetes instalados. Si no se hace otra
pregunta, por defecto rpm retornará el nombre del paquete. Así rpm -qa retornará una lista de
todos los paquetes instalados.
Si se especifica un nombre de paquete, el rpm solicitará sólo aquel paquete. ¿Qué información
retorna? De nuevo, por defecto, retornará el nombre del paquete.
Aunque quizás no es la más informativa de las solicitudes, prince al menos recibe la confirmación
de la instalación del paquete, y un número de versión. Por lo general, cuando se solicita el nombre
del paquete se pide más información. Por ejemplo, al agregar -i se generará un encabezado de
información.
538
[prince@station prince]$ rpm -qi bash
Name : bash Relocations: /usr
Version : 2.05b Vendor: Red Hat, Inc.
Release : 20.1 Build Date: Wed 09 Apr 2003 09:02:36 AM EDT
Install Date: Tue 08 Jul 2003 09:29:33 AM EDT Build Host:
stripples.devel.redhat.com
Group : System Environment/Shells Source RPM: bash-2.05b-20.1.src.rpm
Size : 1619204 License: GPL
Signature : DSA/SHA1, Mon 09 Jun 2003 06:45:19 PM EDT, Key ID 219180cddb42a60e
Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
Summary : The GNU Bourne Again shell (bash).
Description :
The GNU project Bourne Again shell (bash) is a shell or command
language interpreter that is compatible with the Bourne shell
(sh). Bash incorporates useful features from the Korn shell (ksh) and
the C shell (csh) and most sh scripts can be run by bash without
modification. Bash is the default shell for Red Hat Linux.
¿Qué sucede si usted ha encontrado un archivo en el sistema de archivos y quiere conocer a qué
paquete de archivo pertenece? rpm -qf ...
539
[prince@station etc]$ rpm -qf /etc/aep.conf -i
Name : hwcrypto Relocations: (not relocateable)
Version : 1.0 Vendor: Red Hat, Inc.
Release : 14 Build Date: Tue 04 Feb 2003 06:20:37 AM EST
Install Date: Tue 01 Apr 2003 11:27:43 AM EST Build Host:
sylvester.devel.redhat.com
Group : System Environment/Base Source RPM: hwcrypto-1.0-14.src.rpm
Size : 711506 License: GPL
Signature : DSA/SHA1, Mon 24 Feb 2003 01:25:46 AM EST, Key ID
219180cddb42a60ePackager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
Summary : Hardware cryptographic accelerator support.
Description :
This package contains the shared libraries used to interface with
hardware cryptographic accelerators under Linux.
¿Existe documentación en el sistema que pueda dar mayor información acerca de esto? Agregue -l
para listar los archivos relacionados con /etc/aep.conf.
¿Qué sucede si usted se encuentra un archivo de paquete que aún no ha sido instalado en su
sistema? El comando rpm permite que los archivos de paquete sean solicitados con la opción -p.
540
[prince@station RPMS]$ rpm -qil -p xsri-2.1.0-5.i386.rpm
Name : xsri Relocations: (not relocateable)
Version : 2.1.0 Vendor: Red Hat, Inc.
Release : 5 Build Date: Sat 25 Jan 2003 03:37:15 AM EST
Install Date: (not installed) Build Host: porky.devel.redhat.com
Group : Amusements/Graphics Source RPM: xsri-2.1.0-5.src.rpm
Size : 27190 License: GPL
Signature : DSA/SHA1, Mon 24 Feb 2003 12:40:17 AM EST, Key ID 219180cddb42a60ePackager
: Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
Summary : A program for displaying images on the background for X.
Description :
The xsri program allows the display of text, patterns, and images in
the root window, so users can customize the XDM style login screen
and/or the normal X background.
Install xsri if you would like to change the look of your X login
screen and/or X background. It is also used to display the default
background (Red Hat logo).
/usr/bin/xsri
/usr/share/doc/xsri-2.1.0
/usr/share/doc/xsri-2.1.0/README
¿Qué sucedería si usted quisiera generar una lista de los 10 paquetes más grandes instalados en
su sistema? Con el rpm -qai se vería el encabezado de información para cada paquete, el cual se
podría buscar con grep sólo para los tamaños, pero entonces necesitaría nombres. Podría agregar
nombres, pero luego el nombre y el tamaño estarían en líneas separadas. Usted capta la idea.
Para la tarea específica a la mano, prince realiza la siguiente solicitud, (observe que necesita
especificar explícitamente una nueva línea con \n).
541
Justo la información que prince necesitaba. Con una sintaxis de %anchura{nombre de campo} se
puede especificar una anchura de campo opcional. Utilizando esto para limpiar su salida, y
entubándose a sort y a head, prince genera con facilidad una lista de los 10 paquetes más
grandes en su sistema.
Especificaciones
1. Cree el archivo ~/bash_files que contenga una lista de todos los archivos pertenecientes al
paquete bash listando un archivo por línea mediante referencias absolutas.
2. Cree el archivo ~/sshd_man, que liste los tres archivos que contengan las páginas de
manual asociadas con el paquete openssh-server, un archivo por línea mediante
referencias absolutas.
3. En el archivo incluya la palabra que mejor complete la siguiente oración. La biblioteca
/lib/libcap.so.1.* se utiliza para obtener y establecer POSIX.1e __________. (No se
preocupe si no entiende del todo la respuesta).
4. Cree el archivo ~/license_counts que presenta el número de ocurrencias de paquetes que
tienen licencia bajo una licencia determinada para las 5 licencias más utilizadas,
clasificadas en orden numérico descendente. Si se realiza correctamente, su archivo
debería estar formateado como el siguiente. (No se preocupe si las cuentas reales o
nombres de licencia son diferentes. También, usted podría notar lógicamente licencias
similares, tales como LGPL/GPL y GPL/LGPL. No intente combinarlas en una sola
entrada).
content_view let_
Deliverables A title Question 1
542
1. El archivo ~/bash_files, que contiene una lista de todos los archivos pertenecientes al
paquete bash, un archivo por línea, mediante referencias absolutas.
2. El archivo ~/sshd_man que contiene una lista de los tres archivos que proporcionan
páginas de manual para el paquete openssh-server, uno por línea, mediante referencias
absolutas.
3. El archivo ~/whatis_libcap que contiene la respuesta de una palabra para lo que la
biblioteca obtiene y establece.
4. El archivo ~/license_counts que presenta varias licencias bajo las cuales se distribuyen
los paquetes, seguido por el número de paquetes a los cuales se aplica la licencia,
clasificados en orden numérico descendente.
543
Users and Groups
Conceptos clave
• A un nivel inferior los usuarios son representados por un número entero llamado Id del
usuario (uid).
• Cada proceso que se desarrolla en el sistema se ejecuta como un uid dado
• Cada archivo en el sistema de archivos es propiedad de un uid
• El archivo /etc/passwdasigna los uids a las cuentas de usuario.
• Las cuentas de usuarios asignan los uids al nombre del usuario, contraseña, Id de Grupo
(s), directorio de inicio y shell de inicio.
• La contraseña se puede cambiar con el comando passwd .
Discussion
Cuando se utiliza un sistema Linux, usted primero se identifica al entrar con un nombre particular
de usuario nombre de usuario. Su nombre de usuario lo representa a usted. Está asociado con las
cosas que usted hace: cada proceso que se ejecuta en el sistema tiene un nombre de usuario
asociado. Está asociado con las cosas que usted grabe: cada archivo en el sistema está rotulado
como propiedad de un usuario particular. Está asociado con las cosas que usted utiliza: la cantidad
de espacio en el disco que utiliza o la cantidad de tiempo del procesador que usa, pueden ser
rastreados por el nombre de usuario.
Cada usuario en el sistema no sólo tiene un nombre de usuario único, sino también un userid, a
menudo abreviado como uid. Linux rastrea los userids como un número entero de 32bits, es decir
que puede haber más de 2^32 o cerca de 4 mil millones de usuarios. Mientras que a la gente le
gusta pensar en términos de palabras (nombres de usuarios), al Kernel de Linux se le facilita
pensar en términos de números (uids). Cuando el kernel mantiene el rastro de quién es el dueño
del proceso o del archivo, éste recuerda el uid en lugar del nombre del usuario. Sólamente cuando
algún comando produce salida para que la gente lea, el uid se convierte en el nombre de usuario.
El sistema mantiene una base de datos que asigna los nombres de usuarios a los userids. Esta
base de datos se almacena en el archivo de configuración /etc/passwd . Linux, al igual que Unix,
tiene una afortunada tradición: incluso los archivos principales de configuración en el sistema se
mantienen en un texto leíble por humanos y se pueden modificar con un editor de textos. Los
usuarios y administradores pueden usar herramientas sencillas para manejar texto, tales como los
paginadores para examinar las bases de datos. La mayoría de los usuarios en el sistema tiene
permisos para leer, pero no para modificar este archivo. A continuación se verán unas lineas de un
archivo típico/etc/passwd.
544
[elvis@station elvis]$ tail /etc/passwd
apache:x:48:48:Apache:/var/www:/bin/bash
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/html/usage:/sbin/nologin
elvis:x:501:501::/home/elvis:/bin/bash
prince:x:502:502::/home/prince:/bin/bash
madonna:x:504:504::/home/madonna:/bin/bash
blondie:x:505:505::/home/blondie:/bin/bash
sleepy:x:507:507::/home/sleepy:/bin/bash
grumpy:x:509:509::/home/grumpy:/bin/bash
doc:x:510:510::/home/doc:/bin/bash
El archivo /etc/passwd es una configuración de archivo con base en líneas, en donde cada línea
define un usuario en el sistema. Las líneas están divididas internamente en siete campos y cada
campo está separado por una coma. La siguiente tabla explica el uso de cada uno de estos
campos.
Los usuarios rara vez modifican este archivo directamente pero presentaremos varios comandos
que le permitirán al usuario cambiar ciertos campos. Si alguna vez necesita refrescar su memoria;
los campos están documentados en la página man passwd(5).
545
encriptando todas las combinaciones de cada letra hasta encontrar la combinación exacta. Esto se
conoce como un ataque de "fuerza bruta".
En cambio los sistemas de Linux y Unix almacenan las contraseñas utilizando una nueva técnica
llamada "Shadow Passwords", donde las contraseñas de los usuarios se almacenan en un archivo
especializado /etc/shadow. Debido a que el archivo contiene sólo información relacionada con las
contraseñas, sus permisos no permiten ver su contenido. Para mayores detalles vaya a la página
man shadow(5) para obtener mayores detalles.
Los usuarios pueden cambiar su contraseña con un simple comando llamado passwd. Si usted no
es el usuario de root, el comando passwd no aceptará argumentos ni opciones. Su uso individual
permite al usuario cambiar su propia contraseña:
Observe que los usuarios necesitan suministrar su contraseña antes de poder cambiarla. Esto evita
que alguien tome aprovecho de una terminal abandonada por sólo unos segundos.
¡Recuerde su contraseña!
Al escoger una nueva contraseña, con frecuencia los usuarios son amonestados con un
mensaje de BAD PASSWORD. Tradicionalmente, las contraseñas son susceptibles a un tipo
de ataque conocido como un ataque de "diccionarios", en donde un atacante encripta un
diccionario completo (tal como /usr/share/dict/words) y compara la salida encriptada con el
contenido del archivo/etc/shadow.
Para ayudar a evitar ataques de diccionarios, el comando passwd impedirá que los usuarios
utilicen contraseñas demasiado sencillas o fáciles de encontrar en un diccionario.
Usuarios normales
Los usuarios normales representan gente real que utiliza el sistema, estos usuarios
normales generalmente tienen un /bin/bash como shell de inicio de sesión y un directorio
de inicio dentro del directorio /home. Por lo general, los usuarios normales pueden crear
archivos únicamente dentro de sus directorios de inicio y directorios temporales en todo el
546
sistema, tales como /tmp y /var/tmp.En Red Hat Enterprise Linux, los usuarios normales
tienen uids mayores a 500.
El usuario root
El uid 0 está reservado para root, algunas veces llamado el superusuario. El root es el rey
del sistema: puede modificar o remover cualquier archivo; ejecutar cualquier comando;
matar cualquier proceso. El usuario root está encargado de añadir y mantener otros
usuarios, configurar el hardware y agregar el software del sistema. Aunque puede crear
archivos en cualquier parte del sistema, generalmente utiliza su directorio de inicio /root.
La mayoría de los sistemas de Linux reservan un rango de valor bajo de uids para actuar
como usuarios del sistema. Los usuarios del sistema no representan gente, sino
componentes del sistema. Por ejemplo, los procesos que manejan el correo electrónico
usualmente operan como el nombre de usuario correo. Los procesos que ejecutan el
servidor de red Apache operan como el usuario apache. Los usuarios del sistema por lo
general no tienen una shell de inicio de sesión porque no representan gente real.
Asimismo, los directorios de inicio de los usuarios del sistema rara vez residen en /home,
sino que por lo general son directorios de sistema que pertenecen a la aplicación relevante.
Por ejemplo, el usuario Apache, tiene un directorio de inicio /var/www. En Red Hat
Enterprise Linux, los usuarios del sistema tienen uids que van de 1 a 499.
Ejemplos
El usuario elvis quiere averiguar que otra gente está utilizando el sistema Linux y lo que están
haciendo. Lista todos los procesos que están ejecutándose en la máquina actualmente.
547
[elvis@station elvis]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1380 76 ? S 03:33 0:04 init [
root 2 0.0 0.0 0 0 ? SW 03:33 0:00 [keventd]
root 3 0.0 0.0 0 0 ? SW 03:33 0:00 [kapmd]
...
root 872 0.0 0.1 5932 440 ? S 03:34 0:00
[sendmail]
smmsp 881 0.0 0.1 5732 312 ? S 03:34 0:00
[sendmail]
root 891 0.0 0.0 1420 56 ? S 03:34 0:00 gpm -t
ps/2 -m /d
root 900 0.0 0.0 1572 128 ? S 03:34 0:00 crond
xfs 973 0.0 0.0 4812 236 ? S 03:34 0:00 [xfs]
root 992 0.0 0.0 3412 4 ? S 03:34 0:00 rhnsd
--interval
root 999 0.0 0.0 1356 4 tty1 S 03:34 0:00
/sbin/mingetty tt
...
prince 1066 0.0 1.4 18428 3704 ? S 03:37 0:00 /usr/bin/
gnome-se
prince 1116 0.0 0.4 6136 1084 ? S 03:37 0:00
/usr/libexec/bono
prince 1118 0.0 0.6 17380 1716 ? S 03:37 0:00 gnome-
settings-da
prince 1123 0.0 0.1 2688 388 ? S 03:37 0:00 [fam]
prince 1128 0.0 0.4 3816 1032 ? S 03:37 0:02
xscreensaver -nos
prince 1135 0.0 2.1 20220 5440 ? S 03:37 0:06 gnome-
panel --sm-
prince 1137 0.0 3.9 86176 10048 ? S 03:37 0:04 nautilus
--no-def
prince 1145 0.1 3.0 26132 7900 ? S 03:37 0:13 /usr/bin/
python /
root 1146 0.0 0.0 1412 156 ? S 03:37 0:00
[pam_timestamp_c]
prince 1160 0.1 3.4 23208 8844 ? S 03:38 0:11 /usr/bin/
gnome-te
prince 1161 0.0 0.1 1852 284 ? S 03:38 0:00 [gnome-
pty-helpe]
prince 1162 0.0 0.1 4368 340 pts/0 S 03:38 0:00 bash
prince 1210 0.0 0.3 4372 964 pts/1 S 03:39 0:01 bash
prince 2262 0.4 8.0 99276 20476 pts/0 S 03:42 0:36 /usr/bin/
galeon-b
prince 2266 0.0 0.5 5652 1480 ? S 03:42 0:00 oafd
--ac-activat
prince 2818 0.0 0.3 4368 864 pts/2 S 04:17 0:00 bash
prince 3673 0.1 0.5 4356 1444 pts/4 S 05:46 0:00 bash
root 3699 0.0 0.3 4112 952 pts/4 S 05:46 0:00 [su]
elvis 3702 0.0 0.5 4312 1416 pts/4 S 05:46 0:00 -bash
elvis 3736 1.1 4.0 24572 10316 pts/4 S 05:46 0:00 evolution
elvis 3739 0.4 0.8 5664 2260 ? S 05:46 0:00 oafd
--ac-activat
elvis 3742 0.5 2.3 22548 6100 ? S 05:46 0:00 wombat --
oaf-acti
elvis 3746 0.3 1.6 11296 4288 ? S 05:46 0:00 bonobo-
moniker-xm
elvis 3753 1.0 3.4 57400 8916 ? S 05:46 0:00
evolution-mail --
elvis 3755 0.0 0.5 3260 1440 ? S 05:46 0:00 /usr/bin/
gconfd-1
elvis 3762 0.6 2.5 23052 6628 ? S 05:46 0:00
evolution-address
elvis 3766 0.5 2.5 23516 6560 ? S 05:46 0:00
evolution-calenda
elvis 3771 0.5 2.2 21336 5860 ? S 05:46 0:00
evolution-alarm-n
elvis 3773 0.6 2.3 21740 6104 ? S 05:46 548
0:00
evolution-executi
Algunas de las líneas en esta lista bastante larga fueron editadas y remplazadas por "...".
La primera columna de la lista muestra el nombre de usuario que está operando un proceso.
Además de prince, madonna y elvis, - elvis asume que son nombres de usuarios asociados con
gente real, elvis observa que muchos de los procesos en el sistema están ejecutando como el
usuario de root y también como usuarios smmsp y xfs.
La usuaria blondie está examinando el directorio /home y observa que cada directorio de inicio de
usuario le pertenece al nombre de usuario apropiado. Luego utiliza el comando ls -ln para listar el
directorio de propietarios "numéricamente"o por userid en lugar de por nombre de usuario. Preste
mucha atención a la tercera columna en la siguiente lista, la cual muestra un propietario de archivo.
En la lista ls -l, los propietarios de archivo son vistos por nombre de usuario. En la lista ls -ln, los
propietarios de archivo aparecen por userid.
El administrador de la máquina, actuando como root, desea editar el archivo /etc/passwd. Primero,
root tomará un ls -l de los archivos en el directorio /home. Luego, root cambiará el nombre del
usuario sleepy en la base de datos de usuarios y por último, mirará otra vez la salida del comando
ls -l.
549
[root@station root]# ls -l /home/
total 48
drwx------ 4 blondie blondie 4096 May 14 06:40 blondie
drwx------ 4 doc doc 4096 May 14 06:32 doc
drwx------ 4 elvis elvis 4096 May 14 06:31 elvis
drwx------ 4 grumpy grumpy 4096 May 14 06:32 grumpy
drwx------ 4 madonna madonna 4096 May 14 06:31 madonna
drwx------ 4 prince prince 4096 May 14 06:31 prince
drwx------ 4 sleepy sleepy 4096 May 14 06:32 sleepy
[root@station root]# nano /etc/passwd
sleepy:x:507:507::/home/sleepy:/bin/bash
sleepier:x:507:507::/home/sleepy:/bin/bash
... )
En el primer caso el usuario propietario del directorio de inicio de sleepy /home/sleepy aparece
en la lista como sleepy.
En el segundo caso, el usuario propietario del directorio de inicio de sleepy aparecerá en la
lista como sleepier.
¿Qué se puede aprender de este ejemplo? root no cambió nada en /home/sleepy, sólo la base de
datos de usuarios. Sin embargo, tan pronto como el archivo modificado /etc/passwd se grabó, el
comando ls -l comenzó a reportar la nueva información. Esto sugiere lo siguiente:
1. El kernel de Linux no almacena el nombre de usuario del que posee el archivo, sino el
número entero del userid, (del ejemplo anterior, ¿cuál userid es propietario del directorio
/home/sleepy ?).
2. Cada vez que ejecuta el comando ls, debe buscar los trazados del nombre de
usuario/userid en el archivo /etc/passwd para anexar los nombres de usuario a los
propietarios de userid provistos por el kernel.
Especificaciones
550
Al examinar el primer, tercer y último campo (séptimo) del archivo /etc/passwd, determine el userid
y la shell de inicio para su nombre de usuario, el usuario root, y el usuario nobody (sí, hay un
usuario de sistema con el nombre de usuario"nobody"). Cree archivos sencillos en su directorio de
inicio llamado my.uid,my.shell, root.uid, root.shell, nobody.uid, y nobody.shell que contengan sólo la
información apropiada en una sola línea.
Por ejemplo, si el shell de inicio de sesión del usuario nobody fuera /bin/bash, el siguiente comando
crearía fácilmente el archivo apropiado.
Al terminar, los siguientes seis archivos deberían estar en su directorio de inicio, el cual contiene
content_view let_
sólo la siguiente información:
filename Contenido
my.uid Su número entero de userid de cuenta
my.shell Su shell de inicio
root.uid El número entero de userid de root
root.shell La shell de inicio del usuario root
nobody.uid El userid entero del usuario nobody
nobody.shell La shell de inicio del usuario nobody
551
Los grupos Linux y el archivo/etc/group.
Conceptos clave
Discussion
Grupos de Linux
La lección anterior presentó el hecho de que cada proceso se ejecuta bajo el contexto de un
usuario dado. Además, los usuarios, los procesos que estos operan y los archivos que poseen,
pertenecen a la colección de grupos-. Las membresías de grupo le permiten a los administradores
de sistemas manejar eficientemente las colecciones de los usuarios que tienen objetivos similares.
Cada usuario es miembro de un grupo primario. Además, los usuarios pueden ser miembros de
cero o más grupos secundarios. Las implicaciones de los grupos primarios o secundarios se
presentan a continuación.
El archivo /etc/group.
Para el kernel de Linux, un grupo es nombrado usando un id de grupo (GID) de 32 bits, (note la
similitud con que el kernel referencia los usuarios). El archivo /etc/groupasocia nombres de grupo
con GIDs (para humanos) y define los usuarios que pertenecen a cada grupo. El archivo /etc/group,
juega un papel similar para los grupos así como el archivo /etc/passwd lo es para los usuarios,
tiene una estructura similar, y un nombre más razonable. Es un archivo de configuración con base
en líneas, cada línea consta de campos separados por una coma así como se demuestra a
continuación.
wrestle:x:201:ventura,hogan,elvis
physics:x:202:einstein,maxwell,elvis
emperors:x:203:nero,julius,elvis
governor:x:204:ventura,pataki
music:x:205:elvis,blondie,prince,madonna
dwarfs:x:206:sleepy,grumpy,doc
elvis:x:501:
prince:x:502:
madonna:x:504:
blondie:x:505:
552
Los cuatro campos proporcionan la siguiente información:
Las membresías de grupo se utilizan muy a menudo para determinar quién tiene acceso a qué en
el sistema de archivo. Los dwarfs que se encuentran en el siguiente ejemplo del archivo /etc/group
doc, grumpy, y sleepy, podrían estar trabajando en mis prospectos y no querrán que otros usuarios
tengan acceso a su información. Los archivos que están utilizando (y los directorios en los que
están almacenándolos) pueden organizarse de tal manera que cada miembro del grupo dwarfs
tenga acceso a ellos, pero otros usuarios no.
Mientras que los usuarios individuales poseen sus propios archivos, cada archivo tiene al grupo
dwarfs como su propietario de grupo o en otras palabras, cada archivo es "propiedad" del grupo
dwarfs. La primera columma especifica los permisos que tienen el usuario propietario y los
miembros del grupo dueños del archivo. ¿Pueden leerlo? ¿Pueden modificarlo? ¿Cómo interpretar
y manejar estos permisos es el tema del próximo cuaderno. Por ahora, tenga en cuenta quecada
archivo en el sistema de archivos tiene un usuario propietario y un grupo propietario.
Debido a que cada archivo debe tener un grupo propietario, debe haber un grupo por defecto
asociado con cada usuario. Este grupo por defecto se convierte en el propietario del grupo de los
archivos recién creados. Este grupo se conoce como el grupo primariodel usuario. Un grupo de
usuario primario se define en el cuarto campo de una entrada de usuario /etc/passwd.
Aparte del grupo primario, los usuarios pueden optar también por pertenecer a otros grupos. Estos
grupos se llaman grupos secundariosy están definidos (por coincidencia) en el cuarto campo del
archivo /etc/group file.
553
[elvis@station elvis]$ tail /etc/passwd
grumpy:x:509:509::/home/grumpy:/bin/bash
doc:x:510:510::/home/doc:/bin/bash
student:x:2299:2299::/home/student:/bin/bash
ventura:x:511:511::/home/ventura:/bin/bash
hogan:x:512 :512 ::/home/hogan:/bin/bash
pataki:x:513:513::/home/pataki:/bin/bash
einstein:x:514:514::/home/einstein:/bin/bash
maxwell:x:515:515::/home/maxwell:/bin/bash
nero:x:516:516::/home/nero:/bin/bash
julius:x:517:517::/home/julius:/bin/bash
[elvis@station elvis]$ cat /etc/group
...
wrestle:x:201:ventura,hogan ,elvis
physics:x:202:einstein,maxwell,elvis
emperors:x:203:nero,julius,elvis
governor:x:204:ventura,pataki
...
hogan:x:512:
pataki:x:513:
einstein:x:514:
maxwell:x:515:
nero:x:516:
julius:x:517:
En la toma de pantalla anterior se han omitido algunas líneas y se han reemplazado con "...".
En el cuarto campo encontramos que el usuario hogan tiene un id de grupo primario de 512,
(observe que el id del grupo primario hogan es el mismo que su id de usuario. Esto no tiene
que ser el caso, pero lo es a menudo debido a la forma en que se adicionan los usuarios en
Red Hat Enterprise Linux).
Aunque sabemos que el grupo primario de hogan es 512 desde el archivo /etc/passwd, no
podemos conocer el nombre del grupo hasta examinar el archivo/etc/group. Aquí encontramos
que el nombre de grupo del grupo 512 es hogan. En Red Hat Enterprise Linux,el grupo
primario de un usuario casi siempre tiene el mismo nombre del nombre de usuario.
Aquí encontramos que hogan también es miembro del grupo wrestlers. El grupo wrestlers es
un grupo secundario.
554
Los usuarios estándar no tienen permiso para editar el archivo /etc/passwd ni el archivo /etc/group
y por lo tanto, no pueden cambiar las membresías de grupo. Únicamente el usuario administrativo
root, puede cambiar las membresías de grupo.
Si usted no tiene acceso a la máquina como root, las asociaciones de grupo se pueden modificar
utilizando los comandos usermod ygroupmod o la utilidad gráfica system-config-users. El uso
de estos comandos se verá en otro curso.
Ejemplos
En la siguiente lista del directorio /var/spool, prince observa que el grupo "sys" es propietario del
directorio /var/spool/cups.
El usuario prince ahora se está preguntando cuál de los usuarios del sistema es miembro de los
grupos sys. Con el fin de averiguarlo, examina el archivo /etc/group.
Al examinar la cuarta línea, prince determina que los usuarios root, bin y adm son los miembros
actuales del grupo sys.
El usuario prince desea averiguar a qué grupos pertenece el usuario root. Debido al formato del
archivo /etc/group, no puede determinar la respuesta al examinar una sola línea. Decide, entonces,
buscar la palabra "root" en el archivo.
555
[prince@station prince]$ cat /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
adm:x:4:root,adm,daemon
tty:x:5:
disk:x:6:root
lp:x:7:daemon,lp
mem:x:8:
kmem:x:9:
wheel:x:10:root
...
Después de una inspección tediosa de la salida, prince decide que root pertenece a los siguientes
grupos: root, bin, daemon, sys, adm, disk y wheel y piensa para sí que "debe haber una forma más
fácil", (esperemos que prince lea la siguiente lección).
Ejercicios en línea Determinación de membresías de grupo Lab Exercise Objetivo: determinar las
membresías de grupos localmente definidos.Estimated Time: 10 mins.
Especificaciones
Crea un archivo en su directorio de inicio llamado physics.txt, el cual contiene una lista de los
miembros del grupo physics, separados por espacios.
Por ejemplo, si elvis, blondie, y prince fueran los miembros de un grupo physics, el siguiente
comando crearía fácilmente dicho archivo.
Un archivo ~/physics.txt que contenga una lista del grupo physics, separado por espacios.
Determinación de los grupos a los que un usuario está suscritos (la forma difícil) Lab Exercise
Objetivo:Determinar los grupos a los cuales pertenece un usuario definido localmente. Estimated
Time: 10 mins.
Especificaciones
Crea un archivo en su directorio de inicio llamado elvisgrp.txt, el cual contiene una lista de los
grupos a los que el usuario elvis pertenece.
Por ejemplo, si elvis perteneció a los grupos sys, music, y elvis, entonces el siguiente comando
crearía fácilmente dicho archivo.
556
El archivo ~/elvisgrp.txtque contiene una lista de los grupos a los que el usuario elvis pertenece.
557
Revisar la información del usuario
Conceptos clave
Discussion
La lección anterior presentó los conceptos de grupos y la manera cómo los archivos /etc/passwdy /
etc/groupdefinen las membresías de grupo. Debido a que la determinación de las membresías de
grupos desde estos archivos no se hace directamente, los usuarios suelen utilizar el comando id
para determinar la información sobre un usuario.
Opción Efecto
-g,--grupo Escribe únicamente el id de grupo
'G,--grupos Escribe todos los ids de grupo
-u, --user Escribe sólo el identificador de usuario efectivo
-n, --name Imprime el nombre del usuario o del grupo en lugar del número.
[elvis@station elvis]$ id
uid=501(elvis) gid=501(elvis) groups=501(elvis),203(emperors),205(music)
[elvis@station elvis]$ id blondie
uid=505(blondie) gid=505(blondie) groups=505(blondie),205(music)
Por defecto, el comando presenta el identificador de usuario, el grupo primario y todos los grupos
(primario y secundario) a los cuales pertenece el usuario, tanto por nombre de grupo como por id
de grupo.
La salida del comando id puede calificarse con las opciones, como se resume en la tabla anterior.
Por ejemplo, si un usuario solo quizo saber el id del grupo primario de un usuario, el comando
podría ser invocado con la opción -g. Si el usuario quizo conocer el nombre del grupo en lugar del
número, la opción -n también podría especificarse. De la misma manera, la opción -G reportará
todos los grupos , no sólo el grupo primario. Estas líneas de comando son muy útiles cuando el
comando id se utilizado en scripts.
558
[elvis@station elvis]$ id -g blondie
505
[elvis@station elvis]$ id -gn blondie
blondie
[elvis@station elvis]$ id -Gn blondie
blondie music
El comando whoami .
whoami
En Red Hat Enterprise Linux, muy pocas veces hay la necesidad de usar el comando whoami,
porque el intérprete de comandos por defecto bash presenta de inmediato el nombre de usuario
del usuario actual. El intérprete de comandos es configurable, sin embargo, en otros sistemas de
Linux y Unix o en otros entornos (tales como shells de rescate), la identidad del usuario podría no
ser tan obvia. También el comando whoami puede estar insertado en un script, el cual podría tener
un comportamiento diferente dependiendo de quién lo está ejecutando.
Si un usuario quisiera saber quién más está usando una máquina Linux o Unix en particular. Red
Hat Enterprise Linux, provee tres comandos que reportan los usuarios actuales, cada uno con un
nivel diferente de detalle. El más sencillo de estos es el comando users.
users
Puede que el usuario elvis quiera saber quién más está conectado a la máquina.
El comando reporta que blondie, elvis, prince y root están actualmente conectados a la máquina.
¿Por qué elvis aparece en la lista cinco veces? Unix tradicionalmente asocia toda la actividad
desde una sola terminal con lo que técnicamente se llama "sesión". Al utilizar el entorno gráfico X,
cada ventana de una terminal abierta se considera una terminal distinta y por lo tanto, una sesión
diferente. El usuario elvis probablemente está usando terminales múltiples dentro de X windows.
559
Escribe información detallada de quien está actualmente conectado o para el usuario USERNAME,
si es dado.
Opción Efecto
-h salta la cabecera
-s una lista corta
-f no muestra el campo "FROM".
Al igual que el comando users, el comando w lista los usuarios que están conectados en el
sistema, pero provee mucha más información detallada como lo demuestra el usuario elvis:
[elvis@station elvis]$ w
12:58:58 up 1 day, 3:32, 8 users, load average: 0.01, 0.04, 0.04
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty2 - 12:45pm 13:19 0.05s 0.05s -bash
prince tty1 - 12:45pm 13:01 4.63s 4.60s top
elvis rain.rdu station.redhat.c 9:44am 0.00s 5:42 1.58s /usr/bin/gnome
elvis pts/0 station.redhat.c 9:59am 1:05m 5.33s 3.05s mutt
elvis pts/2 station.redhat.c 11:24am 1.00s 0.99s 57.08s /usr/bin/gnome
elvis pts/4 station.redhat.c 11:10am 1:05m 0.20s 0.20s bash
elvis pts/5 station.redhat.c 11:29am 12:37 15.90s 0.16s ssh root
blondie pts/6 station.redhat.c 12:46pm 12:37 0.05s 0.05s -bash
La línea superior da la información resumida: el tiempo actual, el tiempo en días, horas y minutos
que la máquina ha estado funcionando sin interrupciones, el número de usuarios y el promedio
actual de carga (como un promedio de 1.5 y 15 minutos) para la máquina. El comando luego
presenta una tabla con la siguiente información.
Columna Información
USER El nombre de usuario del usuario que está conectado.
TTY La terminal desde donde el usuario está conectado, (la interpretación de las terminales
se discute en el cuaderno 1).
FROM Si el usuario está conectado a la red, el nombre del anfitrión desde donde el usuario
está conectado.
LOGIN@ La hora en que el usuario inició la sesión.
IDLE El tiempo que ha transcurrido desde la última interacción en la terminal.
JCPU La cantidad de tiempo CPU consumido por todos los procesos que están ejecutándose
en el momento asociados con la sesión de la terminal.
PCPU La cantidad de tiempo de CPU consumido por sólo el proceso actual, como se le llama
en el campo "WHAT".
WHAT El proceso del usuario, ejecutándose actualmente.
El último de estos tres comandos similares, who,también provee información detallada acerca de
quién está conectado en el momento. Si se llama sin argumentos, se comporta de una manera
similar al comando w. El comando who también está diseñado para reportar eventos del sistema
tal como el nivel de ejecución actual, ajustes al sistema del reloj y procesos generados por el
proceso /sbin/init. Mucha de esta información va más allá del alcance de este curso.
560
El comando fingerse puede utilizar para "chequear" al usuario, no sólo para ver si está conectado,
sino también si ha leído su correo y la hora en que inició la sesión, entre otras cosas.
Escribe la información sumaria acerca del usuario específico, incluyendo si ha entrado al sistema,
si ha revisado su correo o hace una lista de todos los usuarios en el sistema si no se proporciona
ninguno.
Opción Efecto
-s Salida en formato sumario
-l Salida en formato largo
-p No muestre la información ".plan", ".project", etc.
A manera de ejemplo, el usuario elvis usa el comando finger para ver quién está en el sistema.
Sin argumentos el comando finger actúa de manera muy parecida al comando who, dando
información sumaria incluyendo la de la terminal del usuario (Tty), la hora de inicio y el tiempo de
inactividad.
Ahora elvis nota que su amiga blondie no está conectada y decide buscar más información acerca
de ella.
En este caso el comando finger entrega información sumaria sobre la usuaria blondie, incluyendo
el hecho de que ella nunca ha estado en el sistema y que no tiene correo en espera.
Cuando elvis decide chequear al usuario prince, el comando finger proporciona mucha más
información.
561
[elvis@station elvis]$ finger prince
Login: prince Name: (null)
Directory: /home/prince Shell: /bin/bash
On since Mon May 26 07:10 (EDT) on tty2 10 minutes 30 seconds idle
New mail received Mon May 26 07:17 2003 (EDT)
Unread since Wed May 14 06:31 2003 (EDT)
Plan:
Debido a que prince está conectado en el momento, el comando finger entrega al usuario, la
terminal, la hora de acceso al sistema y el tiempo de inactividad.
El comando finger reporta la úĺtima hora en que el usuario recibió correo y la última vez que lo
leyó, (observe que no sólo funciona si la máquina está configurada para recibir correo-e
directamente, sino que utiliza una cuenta POP provista de un proveedor del servicio de
Internet).
El usuario prince ha creado un archivo ~/.plan que el comando finger reporta.
Un usuario puede personalizar la información que otra persona ve cuando está en finger, creando
archivos ocultos en su directorio de inicio. El comando finger conoce los siguientes archivos.
Nombre de Propósito
archivo
.plan Aparece en pantalla con el comando finger bajo el título "Plan:".
.project Aparece en pantalla con el comando finger bajo el título "Project:".
.pgpkey Aparece en la pantalla gracias al comando finger bajo el título "PGP Key:". Sirve
para que el usuario publique una parte de la clave pública de una clave
pública/privada que se utiliza en la encripción de la clave pública.
Por defecto en Red Hat Enterprise Linux, el directorio de inicio de un usuario no tiene acceso a los
otros directorios de inicio que se encuentran en el sistema . Para que el comando finger encuentre
estos archivos, un usuario debe habilitar los permisos de ejecución en su directorio de inicio
usando un comando similar al siguiente:
562
Ejemplos
[blondie@station blondie]$ id
uid=505(blondie) gid=505(blondie) groups=505(blondie),205(music)
La usuaria blondie quiere ponerse al corriente con el usuario elvis. Ella averigua si elvis está
conectado al sistema utilizando el comando w.
[blondie@station blondie]$ w
08:05:50 up 1:28, 7 users, load average: 0.00, 0.15, 0.34
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
prince tty2 - 9:10am 55:48 0.05s 0.05s -bash
elvis tty1 - 9:09am 55:52 0.01s 0.01s -bash
blondie :0 - 8:40am ? 0.00s 0.83s /usr/bin/gnome-
blondie pts/0 :0.0 8:40am 8:27 10.23s 0.10s bash
blondie pts/1 :0.0 8:41am 2:03 0.54s 0.54s bash
blondie pts/2 :0.0 8:50am 0.00s 0.56s 8.06s /usr/bin/gnome-
blondie pts/3 :0.0 9:04am 59:28 0.20s 8.06s /usr/bin/gnome-
Blondie observa que elvis está conectado pero tiene un tiempo inactivo de cerca de una hora. Al
tratar de decidir si elvis está realmente sentado frente a la terminal, utiliza el comandofinger.
Al ver que elvis ha puesto en la lista una reunión a las 9;30, blondie asume que elvis no está en la
terminal, pero que quedó conectado.
563
El usuario prince desea personalizar lo que los usuarios ven si ellos ejecutan finger. El sabe que
primero necesita permitir el acceso a su directorio de inicio.
...( dentro del editor nano, prince crea el siguiente archivo )...
Por último, prince rutinariamente firma su correo-e con la clave privada GPG. Le gustaría que el
comando finger reportara su clave pública para que la gente pudiera verificar su firma.
mQGiBD7SCMcRBADqfVCpDz/h4ky/K0y2aJoJXaBMRn1KG5fro8PRXa/mH8/ToR9h
n3PdJGCV4glJnMfG2II6+HTm5kgTbg+ACZyvP9JBDGqMpbA2kCQk2RjEEArkL8d4
...
R1ujp1rJ8gCfUtM9p6A5yx5FpPQrsCtKRuurixo=
=315x
-----END PGP PUBLIC KEY BLOCK-----
Plan:
Become the first person to install Red Hat Enterprise Linux on the moon.
564
Algunas veces, los sitios de Internet reconfigurarán su servicio finger de esta manera que en vez
de listar a todos los usuarios conectados en ese momento, el servicio presente una pequeña
cantidad de información. (por lo general cambiante). La usuaria Madonna utiliza el comando finger
para preguntarle a finger.kernel.org por las últimas versiones del kernel de Linux.
Ejercicios en línea
Listado de grupos con el comando id. Lab Exercise Objetivo: Listar las membresías de grupo con
el comando id.Tiempo estimado: 5 minutos.
Especificaciones
Redireccione la salida del comando idpara crear un archivo en su directorio de inicio llamado
mygroups.txt. Utilice el comando apropiado para cambiar la línea de comando, de tal manera que
sus grupos suscritos (primarios y secundarios) aparezcan en una sola línea, separados por un solo
espacio.
Por ejemplo, si los ejercicios se han completado correctamente, el archivo debería tener un formato
similar al siguiente.
Un archivo ~/mygroups.txtque contenga sus grupos suscritos, separados por un espacio en una
sola línea.
Creación de un .plan para el comandofinger. Lab Exercise Objetivo: Crear una respuesta
personalizada para el comando finger.Estimated Time: 10 mins.
Especificaciones
Utilización de un editor de texto o una redirección sencilla del comando echo para crear un archivo
.plan, de tal manera que cuando los usuarios utilicen el comando finger, puedan ver los contenidos
de su plan. Utilice una de sus cuentas alternas para confirmar su configuración.
565
Para que este ejercicio funcione, usted debe permitir que otros usuarios tengan acceso a su
directorio de inicio utilizando el comando chmod o+x ~.
Possible Solution
Al entrar en la consola virtual con una de sus cuentas alternas, debería poder ver su plan como
salida del comandofinger.
Limpieza
Al final de este ejercicio, usted puede cerrar su directorio de inicio restaurando los permisos
originales con chmod o-x ~ (¿Qué ven los otros usuarios en respuesta al comando fingeren este
caso?).
Cambio de identidad
Conceptos clave
Discussion
Cambio de identidad
566
A menudo en Linux, a un usuario le gustaría convertirse temporalmente en otro usuario. Puede que
necesite cambiar los permisos a un archivo del cual no es dueño o puede que un amigo quiera
utilizar su terminal por un momento. El comando que le permite temporalmente cambiar su id de
usuario se llama su.
Opción Efecto
- haga de la shell una shell de inicio.
-c ejecute el comando específico y regrese
-m,-p Preserve el entorno actual
-s, --shell=SHELL Utilice SHELL como la nueva shell de usuario
Convertirse temporalmente en otro usuario puede ser tan simple como "su" a ese usuario.
Observe los obvios problemas de seguridad. Las propiedades y permisos de usuarios no tendrían
sentido si los usuarios pudieran usar su cuando quisieran. Para convertirse en el usuario prince,
era necesario que elvis conociera la contraseña de prince.
Al utilizar el comando su, la nueva shell se convierte en la shell de prince y los procesos iniciados
desde la shell le pertenecen a prince. Sin embargo, la shell se llama una shell de no-inicio, prince
no se registró totalmente- el intérprete de comandos indica que él aún está en el directorio de inicio
de elvis. Aunque la shell y todo lo que ésta inicie, pertenece a prince gran parte del entorno de la
shell fue heredado de elvis.
Para iniciar la sesión como usuario nuevo puede llamar al comando su con un - (un guión simple).
Este especifica que la shell del nuevo usuario debe ser una shell de inicio.
En este caso prince ha ingresado efectivamente, para que el nuevo directorio de trabajo actual de
la shell sea el directorio de inicio de prince, y el entorno de prince se haya inicializado desde su
propia configuración.
La diferencia entre una shell de inicio y una de no-inicio y el uso de las variables de entorno, se
verá con más detalle en otro cuaderno. Por ahora, sólo tenga en cuenta que para llegar a ser
completamente un nuevo usuario, el comando su debería llevar un - y un nombre de usuario.
Convertirse en root
567
Usualmente,un usuario debe ser root para configurar(o arreglar) una máquina Linux. Para
convertirse de un usuario normal a un usuario root, el usuario debe conocer la contraseña de root y
usar el comando "su". Si el comando su se utiliza sin argumentos, éste asume que el usuario está
tratando de convertirse en root.
[elvis@station elvis]$ su -
Password:
[root@station root]#
Debido a que el comando su se llamó con un -, la nueva shell de root comienza en el directorio de
inicio. También observe el cambio sutil en el intérprete de comandos bash. Cuando la shell está se
ejecuta como root, el intérprete de comandos usa "#" en lugar de "$".
El "superusuario"
En Linux y Unix, la cuenta de root se conoce algunas veces como el "superusuario". Este
término probablemente surgió de un malentendido del significado de las letras del comando
su, las cuales se utilizan para convertirse en root. En lugar de superusuario, las letras
significan switch userid - cambio de userid.
En las lecciones anteriores hablamos del papel del grupo primario. Para repasar, cada usuario
tiene un grupo primario como se define en el archivo/etc/passwd y los archivos recién creados son
grupos pertenecientes a un usuario del grupo primario. Algunas veces, puede que los usuarios
quieran convertir uno de sus grupos secundarios en primario para que los archivos recién creados,
sean propiedad de ese grupo. El comando newgrp, equivalente al comando llamado sg hace
justamente esto.
newgrp [[GROUP]]
Genera una nueva shell con GROUP como su grupo primario. Si GROUP no se especifica, utilice
el grupo primario por defecto.
En la siguiente secuencia de comandos, prince creará un nuevo archivo, luego utilizará el comando
newgrppara generar una nueva shell con un grupo primario de music. En la nueva shell, prince
creará otro archivo, el cual pertenecerá al grupo music, prince luego abandonará la nueva shell.
568
[prince@station prince]$ id
uid=502(prince) gid=502(prince) groups=502(prince),205(music)
[prince@station prince]$ date > foo
[prince@station prince]$ ls -l
total 4
-rw-rw-r-- 1 prince prince 29 May 26 12:26 foo
[prince@station prince]$ newgrp music
[prince@station prince]$ id
Ejemplos
Desde la primera consola virtual(tty1), el usuario elvis utiliza el comando su para convertirse en el
usuario prince, observando quién está en la máquina tanto antes como después de usar el
comando su.
[elvis@station elvis]$ w
12:44:38 up 3:44, 1 user, load average: 0.02, 0.07, 0.07
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
elvis tty1 - 12:44pm 0.00s 0.08s 0.02s w
[elvis@station elvis]$ su - prince
Password:
[prince@station prince]$ w
12:44:56 up 3:44, 1 user, load average: 0.02, 0.06, 0.07
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
elvis tty1 - 12:44pm 0.00s 0.13s 0.14s login -- elvis
Para sorpresa del usuario, no hay prueba de que prince haya estado en el sistema. Un listado de
todos los procesos asociados con la primera consola virtual ayuda a ilustrar el porqué.
569
[prince@station prince]$ ps aux | grep tty1
elvis 6115 0.0 0.5 4316 1392 tty1 S 12:44 0:00 -bash
root 6156 0.0 0.3 4112 960 tty1 S 12:44 0:00 su -
prince
prince 6157 0.0 0.5 4316 1404 tty1 S 12:44 0:00 -bash
prince 6207 0.0 0.2 2648 696 tty1 R 12:49 0:00 ps aux
prince 6208 0.0 0.2 3576 644 tty1 S 12:49 0:00 grep tty1
Cuando elvis ejecuta el comando su, el comando su opera como root (esto se conoce como un
suid ejecutable, el cual se tratará con mayor detalle más adelante). Como el comando su, estaba
operando como root, entonces puede iniciar una nueva shell como el usuario prince. La shell
original, como elvis, aún existe y como es el primer proceso que se debe iniciar en la terminaltty1,
aún es propietario de la sesión asociada con esa terminal. El comando w, el cual lista las sesiones,
no sabe de la shell del usuario prince.
Ejercicios en línea
Utilización del comando newgrppara cambiar grupos primarios. Lab Exercise Objetivo: Uso del
comando newgrp para cambiar los grupos primarios y crear un grupo de archivos de propiedad de
un nuevo grupo. Estimated Time: 10 mins.
Especificaciones
Use el comando idpara confirmar que su cuenta es miembro del grupo secundario music.
[student@station student]$ id
uid=2299(student) gid=2299(student)
groups=2299(student),201(wrestle),205(music)
[student@station student]$ ls -l
total 8
-rw-r--r-- 1 student music 29 May 27 08:57 music.txt
-rw-r--r-- 1 student wrestle 29 May 27 08:57 wrestle.txt
570
2. Un archivo titulado ~/wrestle.txtperteneciente al grupo wrestle.
Possible Solution
La siguiente secuencia de comandos brinda una solución posible para crear el archivomusic.txt.
571