Renuncia de responsabilidad:
La versión original de este artículo fue publicada por IBM
developerWorks y es propiedad de Westtech Information Services. Este
documento es una versión actualizada del artículo original y contiene
mejoras introducidas por el Equipo de Documentación de Gentoo.
Este documento carece de soporte activo.
|
Preparación para el examen de certificación 101 LPI (segundo
lanzamiento), Parte 1
1.
Antes de comenzar
Acerca de este tutorial
Bienvenido a “Fundamentos de Linux”, el primero de cuatro
tutoriales diseñado para prepararlo para el examen 101 del
Instituto Profesional de Linux (Linux Professional Institute). En
este tutorial, haremos una introducción a bash (el intérprete de
comandos estándar de Linux), le mostraremos como tomar ventajas
de las órdenes estándar Linux (como ls, cp o mv), explicaremos
inodos, enlaces simbólicos y rígidos (soft y hard links), y mucho
más. Al final de este tutorial, tendrá una base sólida en los
fundamentos de Linux, y estará listo para aprender algunas tareas
básicas de administración de su sistema Linux. Cuando finalice
esta serie de tutoriales (ocho en total) tendrá el conocimiento
necesario para ser un Administrador de Sistemas Linux, y estará
preparado para, si así lo quisiera, la certificación LPIC de nivel
1 del Linux Professional Institute.
Este tutorial en particular (parte I) es ideal para aquellos que
son nuevos en Linux, o para aquellos que quieran revisar o
incrementar sus conocimientos de los conceptos fundamentales de
Linux, tales como copiar y mover archivos, crear enlaces simbólicos
y rígidos, o usar las órdenes estándar de Linux para procesamiento
de textos junto con tuberías (pipelines) y redirecciones.
A lo largo del camino aparecerán consejos, trucos y sugerencias
para mantener el tutorial interesante y práctico, aún para
aquellos con una buena experiencia en Linux. Para los principiantes
este material resultará nuevo, pero los usuarios más experimentados
de Linux verán que este tutorial completará su conocimiento de los
fundamentos de Linux.
Para aquellos quienes han leído la versión 1 de este tutorial por
razones diferentes a las de prepararse para el examen LPI, es
probable que no necesiten leer esta versión. Sin embargo, si
planea presentar los exámenes, debe considerar seriamente
la lectura de este tutorial.
Acerca del autor
Residiendo en Albuquerque, Nuevo México, Daniel Robbins es el
Arquitecto en jefe de la metadistribución Gentoo Linux. También
escribe artículos y seminarios para IBM developerWorks y
Servicios de Desarrollo de Intel, y ha contribuido en la edición
de distintos libros como Samba y Linux SuSE Unleashed. Daniel
disfruta su tiempo con su esposa Mary y su hija Hadassah. Puede
contactarlo en la siguiente dirección: drobbins@gentoo.org.
2.
Introducción a bash
El intérprete de comandos
Si ha usado un sistema Linux, sabrá que cuando ingresa
al sistema (log in) es saludado con un prompt que luce más o
menos así:
Listado de Código 2.1: El prompt |
$
|
El prompt que realmente ve puede lucir un tanto diferente.
Puede contener el nombre de anfitrión de su sistema (hostname),
el nombre de directorio actual de trabajo o ambos. Más allá de
como se vea su prompt lo importante es saber lo siguiente: el
programa que imprimió ese prompt se llama “intérprete de comandos”,
y es muy probable que su intérprete de comandos particular sea uno
llamado bash.
¿Está utilizando bash?
Puede revisar si está utilizando bash tecleando:
Listado de Código 2.2: La variable SHELL |
$ echo $SHELL
/bin/bash
|
Si con la línea de arriba obtuvo un mensaje de error o no
respondió de la misma forma que en nuestro ejemplo, entonces
está usando algún otro intérprete de comandos. En ese caso la mayor
parte de este tutorial puede aplicarse, pero si se está preparando
para el examen 101, le recomendamos cambiar a bash.
Acerca de bash
Bash, es un acrónimo para intérprete de comandos renacido
(Bourne-again-shell), es el intérprete de comandos por omisión en la
mayoría de los sistemas Linux. El trabajo de un intérprete de
comandos es obedecer sus órdenes de manera que pueda interactuar con
su sistema Linux. Cuando termine de introducir órdenes, puede
solicitarle a su intérprete de comandos salir a través de exit o
logout. En ese momento regresará al prompt de inicio de sesión.
A propósito, también puede salir de su sesión tecleando control-D
en el prompt de su bash.
Usando "cd"
Como seguramente habrá notado, situarse en el prompt de su bash
no es la cosa mas emocionante. Así que comencemos a usar bash
para navegar en nuestro sistema de archivos (filesystem). En el
prompt, teclee lo siguiente (sin incluir el $):
Listado de Código 2.3: Cambiar de directorio |
$ cd /
|
Con esto le ha dicho a bash que quiere trabajar en el
directorio /, también conocido como raíz. Todos los directorios
en el sistema forman un árbol, y / es considerado la raíz de
éste. cd establece el directorio donde trabaja actualmente,
también conocido como “directorio actual de trabajo” (current
working directory).
Rutas
Para ver el directorio actual de trabajo de bash, escriba:
Listado de Código 2.4: Directorio actual de trabajo |
$ pwd
/
|
En el ejemplo de arriba, el argumento / es llamado path,
el cual indica hacia donde queremos dirigirnos. En particular,
el argumento / es un path absoluto, es decir especifica
la ubicación relativa a la raíz del árbol del sistema de archivos.
Rutas absolutas
Aquí se muestran otras rutas absolutas:
Listado de Código 2.5: Ejemplos de rutas absolutas |
/dev
/usr
/usr/bin
/usr/local/bin
|
Como puede ver, lo único que estas rutas absolutas tienen en
común es que todas comienzan con /. Si le damos a cd el path
/usr/local/bin, primero cd entrará al directorio /, desde allí
luego entrará al directorio usr, y recién desde allí entrará a
bin. Las rutas absolutas siempre son evaluadas a partir de /.
Rutas relativas
El otro tipo de rutas es el de las rutas relativas.
bash, cd, y otras órdenes siempre interpretan este
tipo de rutas como relativas al directorio actual de trabajo.
Las rutas relativas nunca comienzan con /. Así que si estamos en
/usr:
Listado de Código 2.6: Cambiar de directorio con rutas absolutas |
$ cd /usr
|
Entonces, puede usar una ruta relativa para cambiar el
directorio actual a /usr/local/bin:
Listado de Código 2.7: Cambiar de directorio con rutas relativas |
$ cd local/bin
$ pwd
/usr/local/bin
|
Uso de ..
Las rutas relativas pueden contener uno o mas directorios .. El
directorio .. es un directorio especial que apunta al directorio
padre del actual. De esta manera, y continuando con el ejemplo
anterior:
Listado de Código 2.8: Uso de la notación del 'directorio padre' |
$ pwd
/usr/local/bin
$ cd ..
$ pwd
/usr/local
|
Como puede ver, el directorio actual de trabajo ahora es
/usr/local. De esta forma podemos “volver atrás” un directorio
con respecto al cual estamos situados.
Además, podemos incluir el directorio .. en alguna ruta relativa,
permitiéndonos ir a algún directorio que se encuentre en alguna
rama lateral del árbol de directorios. Por ejemplo:
Listado de Código 2.9: Uso de la notación del directorio padre en rutas relativas |
$ pwd
/usr/local
$ cd ../share
$ pwd
/usr/share
|
Ejemplos de rutas relativas
Las rutas relativas pueden volverse un tanto complejas. Aquí van
algunos ejemplos, ninguno muestra el directorio objetivo.
Intente entender donde quedará situado después de teclear cada
una de estas órdenes:
Listado de Código 2.10: Ejemplos de rutas relativas |
$ cd /bin
$ cd ../usr/share/zoneinfo
$ cd /usr/X11R6/bin
$ cd ../lib/X11
$ cd /usr/bin
$ cd ../bin/../bin
|
Ahora, inténtelo y verifique si sus respuestas son las correctas
:).
Entendiéndolo
Antes de terminar con la orden cd hay algunas cosas más que vale la
pena mencionar. Primero hablaremos de otro directorio especial
llamado ., que se refiere al directorio actual. Aunque este
directorio no suele ser utilizado con la orden cd, si es útil,
por ejemplo, para ejecutar algún programa situado en el
directorio actual, como se ve a continuación:
Listado de Código 2.11: Correr programa desde la ubicación actual |
$ ./miprograma
|
En el ejemplo anterior, se ejecutará el archivo ejecutable
miprograma que reside en el directorio actual de trabajo.
cd y el directorio home
Si lo que quiere es cambiar el directorio actual a su
directorio home, entonces escriba:
Listado de Código 2.12: Ir al directorio HOME |
$ cd
|
Cuando utilice la orden cd sin argumentos, este lo llevará a su
directorio home. Será el directorio /root para el super-usuario,
y /home/nombredeusuario para usuarios comunes. Ahora bien...
¿qué sucede si lo que quiere es referirse a un archivo
situado en su directorio home? Quizás lo que quiera sea
pasar un archivo como argumento a su ejecutable miprograma.
Si el archivo está en su directorio home, entonces puede escribir:
Listado de Código 2.13: Ejecutar un programa en el directorio actual |
$ ./miprograma /home/juanperez/miarchivo.txt
|
Sin embargo, usar rutas absolutas no es siempre lo más conveniente.
Afortunadamente, puede hacer uso del carácter ~ para hacer lo mismo:
Listado de Código 2.14: Uso de la notación 'directorio home' |
$ ./miprograma ~/miarchivo.txt
|
Directorios home de otros usuarios
bash expandirá un simple ~ (tilde) para apuntar a su directorio
home, pero también puede usar el tilde para apuntar a los
directorio home de los otros usuarios. Por ejemplo, si quiere
referirse a un archivo llamado archivodejuan.txt en el directorio
home de juan, entonces puede teclear lo siguiente:
Listado de Código 2.15: Ejemplo del uso de la notación de 'directorio home' |
$ ./miprograma ~juan/archivodejuan.txt
|
3.
Uso de órdenes Linux
Introducción a ls
Ahora, vamos a darle una pequeña mirada a la orden ls. Muy
probablemente ya haya tenido contacto con la orden ls, y
sabe que teclearlo mostrará el contenido del directorio actual
de trabajo:
Listado de Código 3.1: Listado de archivos |
$ cd /usr
$ ls
X11R6 doc i686-pc-linux-gnu lib man
sbin ssl
bin gentoo-x86 include libexec portage
share tmp
distfiles i686-linux info local portage.old src
|
Especificando la opción -a, podrá ver todos los archivos del
directorio, incluyendo los archivos ocultos (aquellos que
comienzan con .). Como se ve en el siguiente ejemplo, ls -a
muestra también los enlaces a directorios especiales . y ..
Listado de Código 3.2: Listado de archivos, incluyendo los ocultos |
$ ls -a
. bin gentoo-x86 include libexec portage
share tmp
.. distfiles i686-linux info local portage.old
src
X11R6 doc i686-pc-linux-gnu lib man sbin
ssl
|
Listado completo de información
A la orden ls le puede especificar uno o más
archivos o directorios a través de la línea de comandos. Si
especifica un archivo, ls solo mostrará este archivo,
pero si especifica un directorio, entonces ls listará el
contenido de ese directorio. La opción -l le
resultará de gran utilidad cuando quiera ver información sobre
permisos, tiempos de modificación, tamaño de los contenidos
listados.
En el siguiente ejemplo, se utiliza la opción -l para
desplegar un listado completo del directorio /usr..
Listado de Código 3.3: Listado de archivos con información completa |
$ ls -l /usr
drwxr-xr-x 7 root root 168 Nov 24 14:02 X11R6
drwxr-xr-x 2 root root 14576 Dec 27 08:56 bin
drwxr-xr-x 2 root root 8856 Dec 26 12:47 distfiles
lrwxrwxrwx 1 root root 9 Dec 22 20:57 doc ->
share/doc
drwxr-xr-x 62 root root 1856 Dec 27 15:54 gentoo-x86
drwxr-xr-x 4 root root 152 Dec 12 23:10 i686-linux
drwxr-xr-x 4 root root 96 Nov 24 13:17
i686-pc-linux-gnu
drwxr-xr-x 54 root root 5992 Dec 24 22:30 include
lrwxrwxrwx 1 root root 10 Dec 22 20:57 info ->
share/info
drwxr-xr-x 28 root root 13552 Dec 26 00:31 lib
drwxr-xr-x 3 root root 72 Nov 25 00:34 libexec
drwxr-xr-x 8 root root 240 Dec 22 20:57 local
lrwxrwxrwx 1 root root 9 Dec 22 20:57 man ->
share/man
lrwxrwxrwx 1 root root 11 Dec 8 07:59 portage
-> gentoo-x86/
drwxr-xr-x 60 root root 1864 Dec 8 07:55 portage.old
drwxr-xr-x 3 root root 3096 Dec 22 20:57 sbin
drwxr-xr-x 46 root root 1144 Dec 24 15:32 share
drwxr-xr-x 8 root root 328 Dec 26 00:07 src
drwxr-xr-x 6 root root 176 Nov 24 14:25 ssl
lrwxrwxrwx 1 root root 10 Dec 22 20:57 tmp ->
../var/tmp
|
La primera columna muestra la información sobre permisos para cada
elemento en la lista. La columna siguiente lista el número de
enlaces para cada objeto del sistema de archivos. La tercer y cuarta
columna listan el propietario del elemento, y el grupo al cual
pertenece, respectivamente. La quinta muestra el tamaño de los
objetos, mientras que la sexta menciona cuando fue realizada la
última modificación del objeto (“last modified time” o “mtime”).
La última columna es el nombre del objeto.
Si el archivo es un enlace simbólico, entonces verá una
flecha -> y la ruta hacia donde apunta el enlace simbólico.
Mirando los directorios
A veces, querrá mirar los directorios, en vez de dentro de
ellos. Para estas situaciones puede especificar la opción -d
, la cual le dirá a ls que mire los directorios, y no dentro
de ellos como normalmente sucede:
Listado de Código 3.4: Listando directorios |
$ ls -dl /usr /usr/bin /usr/X11R6/bin ../share
drwxr-xr-x 4 root root 96 Dec 18 18:17 ../share
drwxr-xr-x 17 root root 576 Dec 24 09:03 /usr
drwxr-xr-x 2 root root 3192 Dec 26 12:52
/usr/X11R6/bin
drwxr-xr-x 2 root root 14576 Dec 27 08:56 /usr/bin
|
Listados recursivos y de inodos
Puede usar -d para mirar un directorio, o puede
utilizar -R para hacer lo opuesto: no sólo mirar dentro
de un directorio, sino que puede mirar recursivamente dentro de
todos los directorios que a su vez se encuentran dentro del
actual. No incluiremos ningún ejemplo de la salida que produce
esta opción (ya que generalmente es muy grande), pero
puede probar con las ordenes ls -R y ls -Rl para
tener una idea de cómo trabajan.
Finalmente, la opción -i para la orden ls puede ser usada
para mostrar el número de inodos de los objetos del sistema de
archivos listados:
Listado de Código 3.5: Listado de inodos |
$ ls -i /usr
1409 X11R6 314258 i686-linux 43090
libexec 13394 sbin
1417 bin 1513 i686-pc-linux-gnu 5120
local 13408 share
8316 distfiles 1517 include 776
man 23779 src
43 doc 1386 info 93892
portage 36737 ssl
70744 gentoo-x86 1585 lib 5132
portage.old 784 tmp
|
Entendiendo inodos
Cada objeto dentro del sistema de archivos tiene asignado un índice único,
llamado un número de inodo. Esto parecería ser trivial,
pero entender el concepto de inodos es esencial para comprender
muchas de las operaciones de un sistema de archivos. Por ejemplo,
considere los links . y .. que aparecen en cada directorio. Para
tener completo entendimiento de qué es realmente el directorio..
primero veamos el número de inodo de /usr/local:
Listado de Código 3.6: Listado de inodo para un directorio |
$ ls -id /usr/local
5120 /usr/local
|
El directorio /usr/local tiene el número de inodo 5120. Ahora,
revisemos el número de inodo de /usr/local/bin/.. :
Listado de Código 3.7: Listado de inodo para un directorio |
$ ls -id /usr/local/bin/..
5120 /usr/local/bin/..
|
Como puede ver, /usr/local/bin/.. tiene el mismo número de inodo
que /usr/local. Veamos como explicar esta impactante revelación.
Hace poco, considerábamos a /usr/local como un directorio.
Ahora, descubrimos que el inodo 5120, es en realidad el
verdadero directorio, y además encontramos dos entradas en el
directorio (también llamadas enlaces), que apuntan a este inodo.
Tanto /usr/local/ como /usr/local/bin/.. son enlaces al inodo
5120. A pesar de que el inodo 5120 existe solamente en un lugar
del disco duro, múltiples enlaces pueden apuntar a él. El inodo
5120 es la verdadera entrada en el disco.
De hecho, es posible ver el número total de veces que el inodo
5120 es referenciado, usando la orden ls -dl:
Listado de Código 3.8: Listado de las referencias al inodo |
$ ls -dl /usr/local
drwxr-xr-x 8 root root 240 Dec 22 20:57 /usr/local
|
Si tomamos la segunda columna de la izquierda, veremos que el
directorio /usr/local (inodo 5120) es referenciado ocho veces.
Aquí va una lista de algunas rutas que, en mi sistema, apuntan a
ese inodo:
Listado de Código 3.9: Referencias al inodo |
/usr/local
/usr/local/.
/usr/local/bin/..
/usr/local/games/..
/usr/local/lib/..
/usr/local/sbin/..
/usr/local/share/..
/usr/local/src/..
|
mkdir
Ahora, veamos brevemente la orden mkdir que puede ser usada para
crear directorios nuevos. El siguiente ejemplo crea tres
directorios nuevos, piedra, papel y tijera, todos dentro de /tmp:
Listado de Código 3.10: Crear directorios |
$ cd /tmp
$ mkdir piedra papel tijera
|
De forma predeterminada, el comando mkdir no creará directorios
padre; la ruta completa hasta el penúltimo elemento
debe existir previamente. De modo que si quiere crear los
directorios ma/ra/villa, tendrá que enviar tres
órdenes separadas de mkdir:
Listado de Código 3.11: Crear directorios padres |
$ mkdir ma/ra/villa
mkdir: cannot create directory `ma/ra/villa': No such file or
directory
$ mkdir ma
$ mkdir ma/ra
$ mkdir ma/ra/villa
|
Sin embargo, mkdir tiene una opción, -p que le indica crear
cualquier directorio padre faltante, como se ve a continuación:
Listado de Código 3.12: Creando directorios padres sobre la marcha |
$ mkdir -p asi/de/facil
|
Bastante sencillo, ¿no?. Para aprender más sobre la orden mkdir
escriba man mkdir, para leer la página de manual. Esto
sirve para casi todos las órdenes que veremos aquí (por ejemplo
man ls), excepto para cd ya que este es una orden interna
(built-in) de bash.
touch
Ahora, revisemos rápidamente las órdenes cp y mv,
usadas para copiar, renombrar y mover archivos y directorios.
Para comenzar, usaremos la orden touch para crear un
archivo en /tmp:
Listado de Código 3.13: Crear un archivo |
$ cd /tmp
$ touch copiame
|
La orden touch actualiza el "mtime" de un archivo si este ya
existe (ver la sexta columna de la salida de la orden ls -l
). Si el archivo no existía, un nuevo archivo vacío es creado.
Ahora debe de tener el archivo /tmp/copiame con un
tamaño de cero.
echo
Ahora que el archivo existe, le agregaremos algunos datos. Esto
lo podemos hacer mediante la orden echo, que toma sus argumentos
y los imprime en la salida estándar. Primero, sólo la orden echo:
Listado de Código 3.14: Creando un archivo utilizando 'echo' |
$ echo "primerarchivo"
primerarchivo
|
Ahora, la misma orden echo pero redireccionando su salida:
Listado de Código 3.15: Redireccionando la salida |
$ echo "primerarchivo" > copiame
|
El signo mayor que > le dice al intérprete de comandos que
escriba la salida de echo a un archivo llamado copiame. Este
archivo será creado si no existe, y será sobrescrito si
existía previamente. Escribiendo ls-l, podemos ver
que ahora el archivo copiame tiene 14 bytes de tamaño, ya que
contiene la palabra primerarchivo y el carácter salto de línea:
Listado de Código 3.16: Ver la información del archivo |
$ ls -l copiame
-rw-r--r-- 1 root root 10 Dec 28 14:13 copiame
|
cat y cp
Para ver los contenidos de un archivo en una terminal, use la
orden cat:
Listado de Código 3.17: Ver contenido del archivo |
$ cat copiame
primerarchivo
|
Ahora podemos hacer una invocación básica de la orden cp
para crear el archivo copiado, siendo este una copia del
original copiame.
Listado de Código 3.18: Copiar archivos |
$ cp copiame copiado
|
Si investigamos, veremos que son distintos archivos, pues sus
números de inodos son diferentes:
Listado de Código 3.19: Revisando las diferencias de inodo |
$ ls -i copiame copiado
648284 copiame 650704 copiado
|
mv
Usemos ahora la orden mv para renombrar “copiame” a “renombrado”.
El número de inodo permanecerá igual; sin embargo, el nombre del
archivo que apunta a él si cambiará.
Listado de Código 3.20: Renombrar un archivo |
$ mv copiame renombrado
$ ls -i renombrado
648284 renombrado
|
Un número de inodo de un archivo movido o renombrado permanecerá
igual mientras el archivo resida en el mismo sistema de archivos que el
archivo fuente. (Veremos más de cerca los sistemas de archivos
en la Parte 3 de esta serie de tutoriales).
Hablando de mv, veamos otra manera de usar la orden mv, ya que
además de permitirnos renombrar archivos, nos permite mover uno
o más archivos hacia otra ubicación en la jerarquía de
directorios. Por ejemplo, para mover /var/tmp/miarchivo.txt
a /home/juanperez, escribiremos:
Listado de Código 3.21: Mover un archivo a una ubicación direfente |
$ mv /var/tmp/miarchivo.txt /home/juanperez
|
Después de teclear la orden, miarchivo.txt será movido a
/var/tmp/miarchivo.txt. Si /home/juanperez
está en un sistema de archivos distinto del de /home/juanperez,
la orden mv se encargará de copiar miarchivo.txt al nuevo
sistema de archivos, y luego borrar el antiguo del sistema de
archivo. Como estará imaginando, cuando miarchivo.txt se
traslada entre sistemas de archivos, el nuevo archivo
miarchivo.txt en la nueva ubicación tendrá un nuevo número de
inodo. Esto es porque cada sistema de archivos tiene su propio
conjunto de inodos independiente.
También podemos usar la orden mv para mover varios archivos a un
mismo directorio. Por ejemplo, para mover miarchivo1.txt y
miarticulo2.txt a /home/juanperez, puede teclear:
Listado de Código 3.22: Mover multiples archivos |
$ mv /var/tmp/miarchivo1.txt /var/tmp/miarticulo2.txt
/home/juanperez
|
4.
Creando enlaces y eliminando archivos
Enlaces rígidos (Hard links)
Hemos mencionado ya el término "enlace" cuando nos referimos a la
relación entre las entradas en los directorios (los nombres que
escribimos) y los inodos (el número de índice en el sistema de
archivos subyacente que usualmente ignoramos). En realidad hay
dos clases de enlaces en Linux, la clase que hemos discutido
hasta aquí son llamados hard links. Un número de inodo dado
puede tener cualquier número de enlaces rígidos, y el inodo
persistirá en el sistema de archivos hasta que el enlace
permanente desaparezca. Cuando el último enlace permanente
desaparece y ningún programa mantiene el archivo abierto, Linux
eliminará el archivo automáticamente. Para crear un nuevo enlace
permanente se utiliza la orden ln:
Listado de Código 4.1: Enlace de archivos |
$ cd /tmp
$ touch primerenlace
$ ln primerenlace segundoenlace
$ ls -i primerenlace segundoenlace
15782 primerenlace 15782 segundoenlace
|
Como podrá ver, los enlaces rígidos trabajan en el nivel de los
inodos para apuntar a un archivo en particular. En los sistemas
Linux, los enlaces rígidos, tienen varias limitaciones. Uno es
que sólo se pueden hacer enlaces rígidos a archivos, y no a
directorios. Así es, aunque . y .. son enlaces rígidos a
directorios creados por el sistema, (ni siquiera como root)
no tiene permitido crear alguno propio. La segunda limitación es
que no pueden expandirse a través de distintos sistemas de
archivos. Esto significa que no puede crear un enlace permanente
desde /usr/bin/bash hacia /bin/bash si sus directorios / y /usr
pertenecen a distintos sistemas de archivos.
Enlaces simbólicos (Symbolic links)
En la práctica, los enlaces simbólicos (symlinks)
usualmente son más utilizados que los enlaces rígidos. Los
enlaces simbólicos son un tipo de archivo especial, donde el enlace se
refiere a otro archivo a través de su nombre, en vez de hacerlo
directamente al inodo. Los enlaces simbólicos no evitan que un archivo sea
borrado, pues si elimina el archivo hacia el cual apunta el
enlace, entonces el enlace simbólico deja de ser útil: se lo considera
roto o inutilizable.
Un enlace simbólico puede ser creado agregando la opción -s a la
orden ln.
Listado de Código 4.2: Ver enlaces simbólicos |
$ ln -s segundoenlace tercerenlace
$ ls -l primerenlace segundoenlace tercerenlace
-rw-rw-r-- 2 arturo arturo 0 Dec 31 19:08 primerenlace
-rw-rw-r-- 2 arturo arturo 0 Dec 31 19:08 segundoenlace
lrwxrwxrwx 1 arturo arturo 10 Dec 31 19:39 tercerenlace
-> segundoenlace
|
En la salida de ls -l los enlaces simbólicos pueden ser
diferenciados de los archivos comunes de tres formas. Por un
lado, en la primer columna un carácter l indica que se trata de
un enlace simbólico. Segundo, el tamaño de un enlace simbólico
es el número de caracteres del archivo apuntado (segundoenlace
en nuestro caso). Por último, en la última columna se ve el
archivo apuntado precedido por una linda flechita ->.
Profundizando enlaces simbólicos
Los enlaces simbólicos son por lo general mucho más flexibles que
los rígidos. Puede crear un enlace simbólico que apunte a
cualquier tipo de objeto del sistema de archivos, incluso
directorios. Y como la implementación de los enlaces simbólicos
está basada en rutas (y no inodos), es perfectamente posible
crear un enlace simbólico que apunte a un objeto de otro sistema
de archivos. Sin embargo, esto también puede hacer más difíciles
de entenderlos.
Considere una situación donde quiere crear un enlace en
/tmp que apunte a /usr/local/bin. Debería escribir algo como esto:
Listado de Código 4.3: Enlazar directorios, primer intento |
$ ln -s /usr/local/bin bin1
$ ls -l bin1
lrwxrwxrwx 1 root root 14 Jan 1 15:42 bin1 ->
/usr/local/bin
|
O alternativamente:
Listado de Código 4.4: Enlazar directorios, segundo intento |
$ ln -s ../usr/local/bin bin2
$ ls -l bin2
lrwxrwxrwx 1 root root 16 Jan 1 15:43 bin2 ->
../usr/local/bin
|
Como podrá ver, ambos enlaces simbólicos apuntan al mismo
directorio. Sin embargo, si el segundo enlace es movido a
otro directorio, entonces quedará "roto" pues la ruta relativa
será incorrecta:
Listado de Código 4.5: Romper un enlace simbólico |
$ ls -l bin2
lrwxrwxrwx 1 root root 16 Jan 1 15:43 bin2 ->
../usr/local/bin
$ mkdir nuevodir
$ mv bin2 nuevodir
$ cd nuevodir
$ cd bin2
bash: cd: bin2: No such file or directory
|
Como el directorio /tmp/usr/local/bin no existe, entonces ya
no podrá cambiar de directorio hacia bin2; en otras
palabras, bin2 ahora está roto.
Por esta razón, es buena idea evitar crear enlaces
simbólicos con rutas relativas. Sin embargo, hay muchos
casos en que sí será útil. Considere por ejemplo el caso que
quiera crear un nombre alternativo para un programa
dentro de /usr/bin:
Listado de Código 4.6: Ver la información del archivo llavero |
# ls -l /usr/bin/llavero
-rwxr-xr-x 1 root root 10150 Dec 12 20:09
/usr/bin/llavero
|
Como usuario root, podría querer crear un nombre
alternativo para “llavero”, como por ejemplo “llave”. En
este ejemplo, teniendo acceso de root (como queda
evidenciado por el prompt de bash: un #). Necesitará poseer
los privilegios de root porque los usuarios comunes no
tienen permitido crear archivos en /usr/bin. Siendo root,
puede crear un nombre alternativo para llavero de la
siguiente manera:
Listado de Código 4.7: Crear enlace simbólico para llavero |
# cd /usr/bin
# ln -s /usr/bin/llavero llave
# ls -l llavero
-rwxr-xr-x 1 root root 10150 Dec 12 20:09
/usr/bin/llavero
# ls -l llave
lrwxrwxrwx 1 root root 17 Mar 27 17:44 llave ->
/usr/bin/llavero
|
En este ejemplo, creamos un enlace simbólico llamado llave que
apunta a al archivo /usr/bin/llavero.
Aunque la solución recién dada funciona, puede llegar a
traernos problemas si decidiéramos mover ambos archivos
(/usr/bin/llavero y /usr/bin/llave) a /usr/local/bin:
Listado de Código 4.8: Mover el enlace simbólico |
# mv /usr/bin/llavero /usr/bin/llave /usr/local/bin
# ls -l /usr/local/bin/llavero
-rwxr-xr-x 1 root root 10150 Dec 12 20:09
/usr/local/bin/llavero
# ls -l /usr/local/bin/llave
lrwxrwxrwx 1 root root 17 Mar 27 17:44 llave ->
/usr/bin/llavero
|
Como hemos usado una ruta absoluta para crear nuestro enlace
permanente, llave aún sigue apuntando a /usr/bin/llavero, y
como acababa de ser trasladado, /usr/bin/llavero no existe
más, pues ahora su ruta es /usr/local/bin/llavero.
Esto entonces significa que llave ahora es un enlace simbólico roto.
Por lo visto tanto los enlaces simbólicos con rutas absolutas como
aquellos con rutas relativas tienen sus méritos, y
deberá elegir el tipo de ruta apropiado para su aplicación.
Frecuentemente ambos tipos de rutas funcionarán bien. El
siguiente ejemplo funcionará aún después de que ambos
archivos sean traslados:
Listado de Código 4.9: Mover archivos con enlaces simbólicos |
# cd /usr/bin
# ln -s llavero llave
# ls -l llave
lrwxrwxrwx 1 root root 8 Jan 5 12:40 llave ->
llavero
# mv llavero llave /usr/local/bin
# ls -l /usr/local/bin/llavero
-rwxr-xr-x 1 root root 10150 Dec 12 20:09
/usr/local/bin/llavero
# ls -l /usr/local/bin/llave
lrwxrwxrwx 1 root root 17 Mar 27 17:44 llave ->
llavero
|
Ahora, escribiendo /usr/local/bin/llave puede ejecutar
el programa llavero. /usr/local/bin/llave apunta al programa
llavero que está en el mismo directorio que llave.
rm
Ahora que conocemos cómo usar las ordenes cp, mv y ln, es
hora de aprender a eliminar objetos de nuestro sistema de
archivos. Usualmente esto puede llevarse a cabo con la orden
rm. Para eliminar archivos, simplemente
especifíquelos con en la línea de comandos:
Listado de Código 4.10: Eliminar archivos |
$ cd /tmp
$ touch arch1 arch2
$ ls -l arch1 arch2
-rw-r--r-- 1 root root 0 Jan 1 16:41 arch1
-rw-r--r-- 1 root root 0 Jan 1 16:41 arch2
$ rm arch1 arch2
$ ls -l arch1 arch2
ls: arch1 : No such file or directory
ls: arch2: No such file or directory
|
Es importante destacar que en Linux, una vez que un archivo es
eliminado, generalmente es para siempre. Por esta razón, muchos
administradores principiantes utilizan la opción -i cuando eliminan
archivos. La opción -i le dice a rm que elimine archivos de modo
interactivo, esto es, preguntando antes de eliminar cada archivo.
Por ejemplo:
Listado de Código 4.11: Eliminar archivos y pedir confirmación |
$ rm -i arch1 arch2
rm: remove regular empty file `arch1'? y
rm: remove regular empty file `arch2'? y
|
En el ejemplo, la orden rm pregunta por cada archivo especificado
si se desea realmente borrar el archivo. Si la respuesta es sí,
deberá teclear una “y” (de yes) seguida de un Enter para cada
pregunta. Si escribe una “n”, el archivo entonces no será removido.
Si hubiera hecho algo realmente mal, podrá abortar la orden en
ejecución (rm -i en nuestro caso) tecleando Control-C. Al
abortarlo, todos los cambios y modificaciones que hubiere
ocasionado ya estarán hechos, pero impediremos que continúe hasta
el final.
Si recién está comenzando a familiarizarse con la orden rm,
puede ser de gran ayuda que agregue la siguiente línea a su archivo
~/.bashrc usando el editor de textos que prefiera, y luego salir y
volver a entrar a la sesión. Ahora, cada vez que escriba rm,
su intérprete de comandos bash lo convertirá automáticamente en la
orden rm -i. De esta manera, rm siempre funcionará de modo
interactivo:
Listado de Código 4.12: Fijar el alias 'rm -i' |
alias rm="rm -i"
|
rmdir
Para remover directorios, tenemos dos opciones. Una es eliminar
primero todo el contenido del directorio y luego usar la orden
rmdir para borrar el directorio mismo:
Listado de Código 4.13: Eliminar directorios |
$ mkdir midir
$ touch midir/arch1
$ rm midir/arch1
$ rmdir midir
|
Este método es comúnmente llamado “eliminación de directorios para
tontos”. Todos los usuarios experimentados y administradores
respetables utilizan la orden rm -rf que veremos a
continuación.
La mejor forma de eliminar un directorio es usando fuerza
recursiva (recursive force) de rm. De esta manera se le indica
a la orden rm que remueva el directorio especificado como así
también todos los objetos dentro del mismo:
Listado de Código 4.14: Eliminar un directorio completamente |
$ rm -rf midir
|
Generalmente, rm -rf es el método preferido para eliminar un árbol
de directorios. Tenga cuidado usando rm -rf ya que su poder puede
ser usado para bien o para mal :).
5.
Usar comodines (Wild cards)
Introducción a comodines
En el uso diario de Linux, hay muchas ocasiones en que
necesitará llevar a cabo alguna operación simple (rm por ejemplo)
en muchos elementos del sistema de archivos simultáneamente. En
estas situaciones, puede llegar a ser tedioso y molesto tener que
teclear cada uno de los archivos en la línea de comandos:
Listado de Código 5.1: Eliminar archivos individualmente |
$ rm arch1 arch2 arch3 arch4 arch5 arch6 arch6 arch8
|
Para resolver este problema, puede tomar ventaja del soporte
de comodines de Linux. Este soporte, también llamado “globbing”
(por razones históricas), le permite a especificar múltiples
archivos al mismo tiempo usando un patrón de comodín (wildcard
pattern). Bash y otras órdenes de Linux interpretarán este
patrón buscando en el disco y encontrarán los archivos que
coincidan con él. Así, si tiene archivos arch1,
arch2,...,arch8 en el directorio actual de trabajo, podrá borrarlos
todos juntos tecleando:
Listado de Código 5.2: Eliminación de archivos usando terminación |
$ rm arch[1-8]
|
O, si quisiera simplemente remover todos los archivos que
comenzaran con arch o que directamente se llamen arch, puede
teclear:
Listado de Código 5.3: Eliminación de archivos usando terminación con * |
$ rm arch*
|
El comodín * coincide con cualquier carácter o secuencia de
caracteres, e incluso con “ningún carácter”. Por supuesto, los
comodines pueden ser usados para muchas cosas además de una simple
eliminación de archivos, como veremos más adelante.
Entendiendo las no-coincidencias (non-matches)
Si quisiera listar todos los objetos del sistema de archivos
de /etc que comiencen con g, como así también que se llame
solamente g, puede teclear:
Listado de Código 5.4: Ejemplo del uso de * |
$ ls -d /etc/g*
/etc/gconf /etc/ggi /etc/gimp /etc/gnome
/etc/gnome-vfs-mime-magic /etc/gpm /etc/group /etc/group-
|
Ahora, veamos que sucede su especificamos un patrón que no coincide
con ningún objeto de sistema de archivos. En el ejemplo siguiente,
trataremos de listar todos los archivos de /usr/bin que comiencen
con asdf y termine con jkl, incluyendo potencialmente el archivo
asdfjkl:
Listado de Código 5.5: Otro ejemplo del uso de * |
$ ls -d /usr/bin/asdf*jkl
ls: /usr/bin/asdf*jkl: No such file or directory
|
Aquí vimos que ocurre. Normalmente, cuando especificamos un patrón,
ese patrón coincide con uno o más archivos del subyacente sistema
de archivos, y bash reemplaza el patrón por una lista de todos
los objetos coincidentes separados entre sí por un espacio vacío
. Sin embargo, cuando no se produce ninguna coincidencia, bash
deja el argumento, comodín y todo, tal cual. Así, cuando
ls no encuentra el archivo /usr/bin/asdf*jkl nos muestra el mensaje
apropiado de error. La regla operativa aquí es que los patrones
deben ser expandidos sólo si coinciden con elementos del sistema de
archivos. De otro modo, permanecen como son y pasan
literalmente al programa con que fueron llamados.
Sintaxis de comodines: * y ?
Ahora que hemos visto como trabaja el englobamiento (globbing)
echaremos una mirada a la sintaxis de los comodines. Puede
usar caracteres especiales para expansión:
* coincidirá con cero o más caracteres. Esto significa que
“cualquier cosa puede ir aquí, incluido nada”. Veamos algunos
ejemplos:
-
/etc/g* coincidirá con todos los archivos del directorio /etc
que comiencen con g, o archivos llamados g.
-
/tmp/mi*1 coincidirá con los archivos de /tmp que comiencen con
mi y terminen con 1, incluyendo el archivo mi1.
? coincide con cualquier carácter simple. Por ejemplo:
-
miarchivo? coincidirá con todos los archivos cuyo nombre consista
de miarchivo seguido de un solo carácter.
-
/tmp/notas?txt coincidirá tanto con /tmp/notas.txt como con
notas_txt si ambos existieran.
Sintaxis de comodines: []
Este tipo de comodín es similar a ?, pero permite ser más
específico. Para usar este comodín, coloque los caracteres que
quisiera hacer coincidir dentro de los corchetes []. La
expresión resultante coincidirá con la ocurrencia de alguno de
esos caracteres. También podrá usar un guión - para especificar un
rango e incluso una combinación de estos. Veamos algunos ejemplos:
-
miarch[12] coincidirá con miarch1 y con miarch2. El comodín se
expandirá mientras aún exista alguno de estos archivos en el
directorio actual.
-
[Cc]hange[Ll]og coincidirá con Changelog, ChangeLog, changeLog y
changelog. Como podrá ver, usar los comodines corchetes es de gran
utilidad para hacer coincidencias con variaciones en letras
mayúsculas.
-
ls /etc/[0-9]* listará todos los objetos del sistema de archivos
del directorio /etc que comiencen con un número.
-
ls /tmp/[A-Za-z]* listará todos los objetos del sistema de archivos
del directorio /tmp que comiencen con un carácter alfabético
(mayúscula o minúscula).
La construcción [!] es similar a [], excepto en que en vez de
coincidir con cualquier carácter de los listados dentro de los
corchetes, coincidirá con los que no han sido listados entre [! y
]. Ejemplo:
-
rm miarch[!9] removerá todos los archivos llamados miarch seguido
de algún único carácter, excepto miarch9.
Advertencias sobre el uso de comodines
Aquí están algunas advertencias para el uso de comodines. Como bash
trata de modo especial los caracteres comodines (?, [, ] y *),
necesitaremos tener cuidado al escribir argumentos de una orden que
contengan algunos de estos caracteres. Por ejemplo, si quisiera
crear un archivo que contenga la cadena de texto [fo]*, la
siguiente línea de comando no lo logrará:
Listado de Código 5.6: Mal uso de caracteres especiales |
$ echo [fo]* > /tmp/archivonuevo.txt
|
Si el patrón [fo]* coincide con algún objeto del directorio actual
de trabajo, entonces encontrará el nombre de estos archivos
dentro de /tmp/archivonuevo.txt en vez de ver literalmente [fo]*
como hubiéramos querido. Para solucionarlo una posibilidad es
rodear los caracteres con comillas simples. De esta manera se le
indica a bash que no realice ninguna expansión de comodines:
Listado de Código 5.7: Evadiendo caracteres especiales |
$ echo '[fo]*' > /tmp/archivonuevo.txt
|
Si utiliza las comillas simples, su nuevo archivo contendrá la
cadena [fo]* como se esperaba. Alternativamente, puede usar
sentencias de escape con barras invertidas para indicarle a bash
que [, ] y * deben ser tratados literalmente en lugar de comodines:
Listado de Código 5.8: Evadiendo caracteres especiales, segunda posibilidad |
$ echo \[fo\]\* > /tmp/archivonuevo.txt
|
Las dos soluciones (comillas simples y sentencias de escape) tienen
el mismo efecto. Y ya que estamos hablando de expresiones con barras
invertidas, es buen momento de mencionar que si quiere
especificar un carácter \, deberá encerrarlo entre comillas simples
o precederlo de otra barra invertida \\ (que será expandido a \).
Nota:
Las comillas dobles funcionan de modo similar a las comillas
sencillas, pero le permiten a bash hacer expansiones limitadas. Por
lo tanto, comillas simples son la mejor opción cuando está
realmente interesado en pasar texto literalmente a una orden. Para
obtener mayor información sobre expansiones de comodines teclee
man 7 glob. Para información sobre comillas escriba man 8
glob y lea la sección titulada QUOTING (COMILLAS). Si está
realmente planeando rendir los exámenes LPI considere esto una
tarea :).
|
6.
Resumen y bibliografía
Resumen
Felicitaciones; ha llegado al final de nuestra reseña sobre los
fundamentos de Linux. Esperamos que haya sido de ayuda para
reafirmar sus conocimientos de Linux. Los temas que ha aprendido
aquí, las bases de bash, órdenes básicas de Linux, enlaces y
comodines, sientan las bases para el próximo tutorial sobre
administración básica. En él se cubren temas como expresiones
regulares, permisos y propiedad y gerenciamiento de cuentas de
usuarios entre otras cosas.
Continuando con esta serie de tutoriales, pronto estará listo
para probar el nivel 1 de Certificación del Linux Professional
Institute. Y hablando de la certificación LPIC, si esto es algo que
le interesa, entonces le recomendamos que estudie las bibliografías
sugeridas de la siguiente sección, las cuales han sido
cuidadosamente seleccionadas para aumentar y reforzar lo cubierto
en este tutorial.
Bibliografía
En la serie de artículos “Bash con ejemplos” de developerWorks, se
muestra cómo usar los programas constructores de bash para escribir
sus propios guiones de bash. Esta serie (particularmente la parte 1
y 2) será una buena preparación para el examen LPIC nivel 1:
Si es un usuario Linux principiante o intermedio, es
altamente recomendable revisar las preguntas técnicas para usuarios
Linux, un listado de 50 páginas que muestran la lista de preguntas
más frecuentes de Linux con respuestas detalladas. El FAQ es un
archivo formato PDF (Acrobat).
Si no está familiarizado con el editor vi, vea el tutorial de
developerWorks "Intro to vi". Este tutorial le da una introducción
rápida a este poderoso editor de texto. Considérelo como un
material del tipo "debe leer" si no sabe cómo utilizar vi.
|