Comandos Basicos Linux
Comandos Basicos Linux
Comandos Básicos de Linux
Terminales Virtuales o SHELL de Comandos
Cuando nos conectamos al sistema, disponemos de un Terminal asociado, que lo componen la
pantalla y el teclado. Sin embargo, Linux posee una característica que lo hace muy especial, puede
manejar arias sesiones de conexión a la vez a través de un mismo Terminal. Estas sesiones se conocen
como terminales virtuales o consolas virtuales. Todas las conexiones estarán asociadas al mismo
Terminal pero cada una puede estar conectada a un usuario diferente y estar realizando tareas
diferentes.
Existen varios terminales virtuales activados al entrar al sistema, que puede variar entre cuatro y
siete terminales, si bien este número se puede ampliar. Esto es muy útil porque, por ejemplo, si nos falla
algún proceso en un Terminal, y este queda bloqueado, podemos conectarnos por otro Terminal virtual
y desbloquear el primero. Además, podemos ejecutar procesos que requieren una gran cantidad de
procesado, tiempo en el que el Terminal queda en suspensión y podemos cambiar a otro para realizar
tareas.
1
Administración de Sistemas Linux Comandos Básicos de Linux
Interpretes de Comandos
Toda acción realizada en Linux es supervisada por el núcleo. El intérprete de comandos,
conocido por Shell, es un programa que se carga al final del inicio de la sesión cuando nos conectamos
al sistema, y es quien ejecuta todas nuestras órdenes. Existen varios tipos de intérpretes de comandos, si
bien todos son muy similares.
El shell es el programa que interpreta los comandos que tecleamos en la línea de comandos y
decide las acciones a tomar, como el famoso [Link] del DOS. A entrar en el sistema se ejecuta
un interprete de comandos por defecto, aunque el interprete de comandos utilizado se puede cambiar
por otro que tengamos también instalado en el sistema, invocando el nuevo interprete de comando como
si fuera un comando mas del viejo interprete de comandos.
Para conocer el interprete de comandos que estamos usando, existe una variable de entorno en
ele sistema que contiene esa información, para ver le contenido de las variables de entorno (que
contienen ciertos parámetros del sistema), solo tenemos que escribir en la línea de comandos echo
$variable, en este caso echo $SHELL y obtendremos esa formación. El intérprete de comandos se
ejecuta nada más entrar en el sistema, y tras su carga en memoria, este procede a ejecutar ciertos
ficheros de configuración de arranque que generalmente son el fichero de arranque de sistema
/etc/profile, que está presente para todos los usuarios y siempre se ejecuta.
El tipo de intérprete de comandos que elegimos viene a ser equivalente a elegir el intérprete de
comandos que queremos utilizar al entrar en el sistema. La apariencia es parecida pero cada uno tiene
unas características propias que lo hacen diferentes. Los más utilizados son el csh, bash y tcsh., que
incluyen una programación parecida al lenguaje C. los shell script son archivos de texto que el
intérprete de comandos entiende sin problemas, sin necesidad de compilar ese código.
El sistema Linux posee, al igual que UNIX, varios tipos de Intérpretes de comandos estándares:
• Sh (Bourne Shell). Es uno de los intérpretes de comandos más antiguos y más estandarizados.
La mayoría de los intérpretes de comandos son compatibles hacia atrás con este intérprete de
comandos.
• Bash (Bourne again shell). Se trata de uno de los intérpretes de comandos más avanzado, pero
totalmente compatible con el intérprete de comandos sh. Suele ser el intérprete de comandos
por defecto de muchos sistemas Linux. Incorpora características de los intérpretes de comandos
sh, rsh, ksh y csh.
• Csh (C Shell). Fue desarrollado por Hill Joy como una ampliación del intérprete de comandos
sh de Unix. Desarrollado en Berkley. Es totalmente compatible con el intérprete de comandos
estándar y un amplio numero de extensiones de este. Posee una sintaxis similar a la del lenguaje
e programación C y es bastante diferente de la del interprete de comandos estándar. Resulta muy
cómodo para programar en C. Es muy utilizado y esta disponible en la mayoría de las
distribuciones de Linux.
• Tcsh (Tiny C shell). Un csh para sistemas de menor tamaño. Esta muy optimizado.
2
Administración de Sistemas Linux Comandos Básicos de Linux
Comandos para el manejo de Ficheros y Directorios
Ciertamente, todos estos conocimientos que estamos citando pueden casi siempre aplicarse a otras ter
minales como sh, pero nos referimos a BASH por ser la que viene por defecto con Linux. Ahora vamos
a explicar el concepto de DIRECTORIO DE TRABAJO o directorio actual. En esta línea:
[usuario@maquina usuario]$
estamos trabajando en el directorio /home/usuario. ¿Qué quiere decir esto? Pues es fácil, que podemos
"hacer referencia" a un archivo desde un comando simplemente con el nombre de archivo y no su ruta
completa si éste está en /home/usuario porque es el directorio de trabajo actual. Un ejemplo rápido, va
mos a editar un archivo para comprender esto, no te preocupes por el comando vim, puesto que lo vere
mos más adelante. Si estamos en /home/usuario y tenemos un archivo que se llama /home/usuario/mi
texto, para editarlo, bastaría con hacer:
[usuario@maquina usuario]$ vim mitexto
Como estamos trabajando en el directorio /home/usuario y el archivo que queríamos editar también
está en el directorio de trabajo, el editorlo encontraría sin problemas. Esto sería equivalente a hacer:
[usuario@maquina usuario]$ vim /home/usuario/mitexto
pero como acabas de ver, teclear la ruta completa no es en absoluto necesario si el objetivo de nuestro
comando está en el directorio de trabajo.
Referencias Relativas
Este concepto es también sencillo. Partimos de que estamos otra vez en /home/usuario (de
nuevo no te preocupes por vim, el comando del editor, lo usamos como un ejemplo para que veas las
referencias, no es necesario que pruebes esto porque vamos a explicarlo más adelante), y queremos edi
tar un archivo que está en /home/usuario/documentos/mitexto. Al estar en /home/usuario, basta
ría con hacer:
[usuario@maquina usuario]$ vim documentos/mitexto
Pero como ya hemos visto, con la referencia relativa al directorio en el que nos encontramos es
suficiente. Por esto ya has podido observar que podemos referirnos a los archivos de dos formas
distintas: mediante una referencia relativa al directorio actual en el que nos encontramos o mediante
una REFERENCIA ABSOLUTA. Las referencias absolutas comienzan siempre desde la raíz del
sistema de archivos, /, y por eso siempre empiezan con / e indican la RUTA COMPLETA al archivo al
que nos estamos refiriendo.
3
Administración de Sistemas Linux Comandos Básicos de Linux
El comando cd
Este sencillo comando, lo que nos va a permitir es cambiar nuestro directorio de trabajo (o di
rectorio actual). Es una abreviatura (como muchos otros comandos) de lo que hace, en este caso de
Change Directory. Podemos necesitar cambiar nuestro directorio de trabajo si vamos a trabajar con mu
chos archivos que estén en el direcotrio al que nos cambiamos, y no queremos teclear siempres su ruta
completa por resultar esto demasiado incómodo y largo. Partimos de /home/usuario, y nos queremos
cambiar a /usr/local, que es donde residen muchas cosas personalizadas de nuestro sistema. Se po
dría hacer de la siguiente forma:
[usuario@maquina usuario]$ cd /usr/local/
Y entonces ya estaríamos en /usr/local:
[usuario@maquina local]$pwd
Si simplemente escribimos cd, sin ningún argumento (dato que necesita un comando para ope
rar de una manera u otra, con un archivo u otro... como después veremos), lo que hará será llevarnos a
nuestro directorio personal:
[usuario@maquina local]$ cd
[usuario@maquina usuario]$
Como puedes ver, ahora nuestro directorio de trabajo es /home/usuario, que es nuestro
directorio personal.
Pero hay algunas cosas que no hemos contado de las referencias relativas. Es que dos puntos se
guidos .. se refieren al directorio inmediatamente anterior (superior) al que nos encontramos, y un
punto . se refiere al directorio en el que nos encontramos (directorio actual). Si estando en
/home/usuario escribes cd ., te darás cuenta de que no cambia de directorio, se queda en el actual, de
la misma manera que si hubieras hecho cd .. te habría llevado a /home , el directorio inmediatamente
superior. Estos dos comandos equivaldrían a cd ./ y cd ../; es lo mismo, pero es realente con la ba
rra como deben utilizarse estos comandos (puesto que nos estamos refiriendo a directorios). Utilizarlos
sin ella, puede dar lugar a confusión y equivocaciones (recuerda que los archivos y directorios ocultos
comienzan su nombre por .). Ahora ya sabes que para poder ir a /home/usuario/documentos podría
mos haber hecho:
[usuario@maquina local]$ cd ./documentos
Lo cual no es muy eficiente en este caso, pero como veremos más adelante, es de obligada utili
zación para ejecutar un comando en el directorio actual si este directorio actual no está en la PATH.
Por ejemplo para ejecutar un programa (como veremos más adelante) que estuviese en /home/usua
rio, al no estar esta ruta en $PATH, necesitaríamos hacerlo así (estando en /home/usuario):
[usuario@maquina local]$ ./miprograma
Archivos y Directorios
Ahora vamos a trabajar con archivos y directorios, vamos a crear directorios, los borraremos,
listaremos archivos... Todo esto no es difícil de hacer. Si recordamos, es preferible que trabajemos
4
Administración de Sistemas Linux Comandos Básicos de Linux
como un usuario normal y no como root, para no dañar nuestro sistema por accidente intentando borrar
un directorio importante. Empezaremos con obtener un listado de los contenidos del directorio /. Este
se hace con el comando ls. Las opciones (indican al comando la forma en la que debe trabajar) que tie
ne el comando ls son principalmente -a y –l, -a indica que se muestren todos los archivos, incluso los
ocultos, y -l muestra un listado largo, con detalles como el usuario al que pertenece el archivo, los per
misos de ese archivo y algunas cosas más. Los parámetros que toma ls principalmente es un directorio.
Si no se especifica ninguno, saca un listado del directorio actual. Veamos algunos ejemplos:
[usuario@maquina local]$ ls
Desktop Mail documentos programas proyectos
[usuario@maquina usuario]$
Esto es un listado de los archivos y directorios que contiene el directorio actual, en este caso
/home/usuario. En algunas distribuciones, los directorios aparecen en color azul, los ejecutables en
color verde, etc. pero muchas veces no hay distinción.
[usuario@maquina local]$ ls –l
total 1
drwxr-xr-x 2 douglas users 48 2005-11-22 13:52 bin
drwx------ 2 douglas users 80 2005-11-22 13:52 Documents
drwxr-xr-x 15 douglas users 1272 2005-11-28 16:12 public_html
Como puedes ver, la opción -l nos devuelve un listado largo, en el que apreciamos permisos
(que explicaremos más adelante), dueño y grupo de archivo, fecha, nombre, tamaño, y algunos otros
detalles.
[usuario@maquina local]$ ls -a
. Documents .kermrc public_html .xemacs
.. .dvipsrc .mozilla .ssh .[Link]
.bash_history .emacs .muttrc .urlview .[Link]
.bashrc .exrc .mysql_history .viminfo .xtalkrc
bin .fonts .profile .xcoralrc
Aquí puedes ver un listado de todos los archivos y directorios, incluidos los ocultos. Podríamos
emplear las dos opciones juntas, como ls -la o ls -al, lo que nos devolvería un listado largo con
todos los archivos, ocultos incluidos. Si tienes cualquier duda o quieres saber qué parámetros acepta un
comando, simplemente escribee comando --help y verás una lista de opciones y argumentos que
puedes usar con ese comando.
Pasemos a ver ahora cómo podemos crear un directorio. Por intuición puede determinarse que
se puede crear un directorio en un lugar en el que no tienes permiso para ello. Generalmente, un
usuario normal sólo tendrá permiso para ello en su directorio de usuario, /home/usuario, así que
cámbiate ahí si no es donde estás. Para crear directorios podemos utilizar tanto referencias relativas al
directorio actual como referencias absolutas al sistema de archivos. Para crear directorios, basta con
usar el comando mkdir. Crearemos un directorio en /home/usuario llamado pruebas, y otro dentro de
este llamado pruebas1 como ejemplo:
5
Administración de Sistemas Linux Comandos Básicos de Linux
Segunda forma de hacerlo:
[usuario@maquina local]$ mkdir pruebas
[usuario@maquina local]$ mkdir pruebas/pruebas
Tercera forma de hacerlo
[usuario@maquina local]$ mkdir /home/usuario/pruebas
[usuario@maquina local]$ mkdir /home/usuario/pruebas/pruebas1
Ahora vamos a mover y copiar archivos a esos directorios. Para mover archivos y directorios
usaremos el comando mv. Date cuenta que este comando también nos permite renombrar un archivo.
Supongamos que tenemos un archivo llamado miarchivo en /home/usuario. Vamos a renombrarlo a
minuevoarchivo (es recomendable no usar espacios en los nombres de archivo, puedes usar guiones
bajos (_) en sustitución de los espacios; asimismo es recomendable como ya tratabamos, no usar
acentos en los nombres de archivo):
[usuario@maquina local]$ cd /home/usuario
Primera forma de hacerlo:
[usuario@maquina local]$ mv miarchivo minuevoarchivo
Tercera forma de hacerlo:
[usuario@maquina local]$ mv /home/usuario/miarchivo minuevoarchivo
Podemos renombrar directorios también, y moverlos unos dentro de otros. Para mover un
directorio llamado programas y llevarlo dentro de otro llamado pruebas, haríamos algo como esto:
[usuario@maquina local]$ mv programas/ pruebas/
De esta forma el directorio programas se queda dentro de pruebas. Como ves, el comando mv
toma como primer argumento el fichero o directorio origen, y como segundo argumento el destino;
recuérdalo. Podríamos reestablecer el directorio programas al nivel anterior donde estaba
[usuario@maquina local]$ cd pruebas/
[usuario@maquina local]$ mv programas ../
6
Administración de Sistemas Linux Comandos Básicos de Linux
Como habrás podido apreciar y ya hemos dicho, el comando mvtoma primero lo que se quiere
mover y después a dónde se quiere mover. Para dominarlo totalmente, lo mejor es que practiques, es la
única forma de comprender cómo se comporta bajo determinadas situaciones este comando, y de que tú
lo domines.
Para borrar un directorio, si este esta vacío, usaremos el comando rmdir. Por ejemplo vamos a
borrar los directorios pruebas1 y pruebas que creamos anteriormente. Si recuerdas, pruebas1
estaba dentro de pruebas:
[usuario@maquina local]$ ls
pruebas
[usuario@maquina local]$ rmdir pruebas/
rmdir: `pruebas': El directorio no está vacío / Directory not empty
#Como ves, no podemos borrarlo porque no está vacío
[usuario@maquina local]$ cd pruebas/
[usuario@maquina local]$ ls
pruebas1
[usuario@maquina local]$ rmdir pruebas1
# pruebas1 está vacío y por lo tanto se borra
[usuario@maquina local]$ cd ../
[usuario@maquina local]$ rmdir pruebas
#Ahora pruebas está vacío y también se borra
(Las líneas que comienzan por # son explicaciones del manual para que comprendas lo que pasa). Está
claro que hacer todo esto para borrar un directorio y todo lo que éste contenga no es del todo cómodo.
Unas líneas más adelante veremos cómo es posible borrar todo un directorio con todo lo que contenga
por debajo de él (siempre que tengamos los permisos adecuados sobre todo lo que contiene y sobre el
directorio mismo).
Si tenemos los permisos adecuados sobre él, minuevoarchivo será borrado, en la mayoría de
los casos sin preguntarnos, por lo cual debemos tener bastante cuidado con lo que hacemos con los
archivos de nuestro sistema, porque una vez borrados es imposible volver a recuperarlos (¿para que los
borraríamos entonces si siguiesen estando ahí?). Al igual que todos los comandos anteriores, rm es muy
potente y sobre todo muy flexible. Veremos cómo es capaz de borrar un directorio con todo lo que
tenga por debajo.
7
Administración de Sistemas Linux Comandos Básicos de Linux
La opción -r nos permite de igual forma copiar un directorio entero. Supongamos que
quisiéramos copiar el directorio pruebas (con todo su contenido) a un nuevo directorio llamado
pruebas2 que crearemos al mismo nivel que pruebas:
[usuario@maquina local]$ cp -rf pruebas/ pruebas2/
8
Administración de Sistemas Linux Comandos Básicos de Linux
Permisos, Grupos y Usuarios
Administracion de Usuarios
Linux es un sistema multiusuario por lo que es necesario la administración (segura) de los
distintos usuarios que van a hacer uso de los recursos del sistema. De momento no vamos a dar grandes
nociones de seguridad, pero sí una introducción a los tipos de usuarios y qué privilegios deben tener.
Dentro de un sistema existen al menos 3 tipos de usuarios.
• Usuarios normales con más o menos privilegios que harán uso de los recursos del sistema. Son
generalmente inexpertos y propensos a causar problemas. Simplemente deben poder usar
algunos programas y disponer de un directorio de trabajo.
• Usuarios de Sistema son aquellos encargados de los demonios del sistema, recordemos que para
Linux todo es un fichero, el cual tiene un dueño y ese dueño tiene privilegios sobre él. Así, es
necesario que algún usuario del sistema posea los procesos de los demonios, como veremos más
adelante. Resumiendo, es necesario que para algunos servicios del sistema se creen usuarios
(generalmente para demonios). Como puede ser el caso de Mail, irc... Estos usuarios tendrán los
privilegios necesarios para poder hacer su tarea, gestionar estos usuarios es de gran
importancia. No obstante, este tipo de usuarios no necesita que se le asigne un shell, puesto que
simplemente poseerán los demonios, pero no será necesario que hagan login en el sistema.
• ROOT: Se debe tener cuidado con lo que se hace al entrar en el sistema como root. Él lo puede
todo, en principio no hay restricciones para ÉL (aunque algunos programas nos avisarán de que
estamos haciendo una auténtica burrada desde el punto de vista de la seguridad).
Además del criterio anterior, existe un criterio secundario para clasificar a los usuarios de un
sistema. Ya vamos conociendo la tendencia de los UNIX y Linux, primero, por hacer que casi todo sea
un fichero, y segundo, por hacer que absolutamente todo tenga un dueño (como iremos descubriendo a
medida que usamos el sistema, nada se deja al azar en este aspecto), incluidos los procesos que se están
ejecutando en el sistema. Otro concepto que lleva a esta segunda clasificación es, el de los usuarios de
los servicios del host. Este tipo de usuarios simplemente accede remotamente a algunos servicios de
nuestra máquina, tales como correoelectrónico o FTP. Esto nos lleva a definir:
• Usuarios de login. Estos primeros, pueden hacer login en el sistema y usar una shell en él. Es
decir, tienen una shell válida de inicio (como se indica más abajo), generalmente, /bin/bash.
• Usuarios sin login. Este tipo de usuarios, bien son usuarios de sistema, o bien usuarios de los
servicios del host. En ambos casos no pueden hacer login en el sistema directamente ni usar un
shell. En otras palabras, no tienen asignado un shell válido. Su misión, es "poseer" algunos
archivos y directorios del sistema, y manejarlos restringidamente a través de algunos programas
(el servidor FTP, el servidor de correo electrónico, etc. darán a los usuarios de los servicios del
host los privilegios suficientes: almacenar mensajes, etc.). En el caso de los usuarios de sistema,
poseerán además algunos procesos.
La administración de usuarios se realiza en todas las distribuciones de manera muy parecida,
dada la herencia UNIX, aunque en el fondo todas hacen lo mismo. Según la política que lleven lo
pueden realizar de una manera u otra, por lo que aquí veremos la forma la forma interna de trabajar de
los programas a la hora de añadir o quitar usuarios, y al final expondremos ejemplos concretos de las
9
Administración de Sistemas Linux Comandos Básicos de Linux
distros más conocidas.
¿Cómo añadir un usuario al sistema? Hay que seguir una serie de pasos que relatamos a continuación.
Pero antes veremos la estructura de los archivos que vamos a tocar.
• /etc/password Archivo que mantiene la base de datos de los usuarios del sistema y tiene
la siguiente forma:
nombre_de_usuario:password(si es shadow será x):uid:gid:comentario:home_del_usuario:shell
Estos campos son:
1. Nombre de Usuario Es el nombre con el que entrará en el sistema.
2. Password La palabra de paso necesaria para entrar (cifrada). Si nuestro sistema usa shadow
(explicado después), este campo será una x.
3. UID (User ID) Número que lo identifica en el sistema, recordemos que los ordenadores se
llevan mejor con los números.
4. GID (Group ID) Número que identifica al grupo principal al que pertenece el usuario.
5. Comentario Opcional, si es necesario aclarar algo, esto solo es para el administrador, pues
el sistema no lo usa.
6. home_del_usuario Ruta absoluta del directorio de trabajo del usuario.
7. Shell Intérprete de comandos del usuario, que será el que use inmediatamente después de
entrar en el sistema, por defecto es /bin/bash. Para usuarios sin login, aunque puede que
ahora no lo necesites, la shell no válida típica para poner en este campo es /bin/false.
• Shell Intérprete de comandos del usuario, que será el que use inmediatamente después de
entrar en el sistema, por defecto es /bin/bash. Para usuarios sin login, aunque puede que
ahora no lo necesites, la shell no válida típica para poner en este campo es /bin/false.
nombre_grupo:password:GID:lista_usuarios
1. Nombre del Grupo Por defecto con los comandos habituales se crea un grupo con el mismo
nombre que el usuario creado, aunque pueden existir otros grupos con nombres específicos.
2. password Se usa para dar a una serie de individuos un mismo directorio con una cuenta
común.
3. GID (Group ID) Número de Identificación en el Sistema del grupo.
4. lista de usuarios que pertenecen al grupo, separados por comas.
• /etc/shadow Para sistemas que usen shadow, que no es más que una medida de seguridad.
Los sistemas que no usan shadow guardan el password en /etc/passwd pero este archivo
tiene la peculiaridad de que debe ser legible por todo el mundo, si no, no podría ni hacerse un ls.
Este archivo podría caer en manos de un usuario ilegítimo y este ejercer técnicas de crackeo
sobre las claves. Como solución del problema lo que se hace es almacenar todos los datos de los
usuarios en el /etc/password menos sus contraseñas; que se almacenan en
/etc/shadow, el cual sí tiene restringidos los permisos y no es accesible por los usuarios
normales.
10
Administración de Sistemas Linux Comandos Básicos de Linux
usuario:password:días del último cambio: dias antes del cambio:Dias despues del cambio:
tiempo de aviso:dias antes de la inhabilitacion: perido que lleva caducado:reservado:
1. Usuario Nombre del usuario.
2. password Aquí sí, es el password cifrado.
3. Tiempo del último cambio de password Pero el tiempo cuenta desde el 1 de
enero de 1970, comienzo de la era UNIX.
4. Días antes del cambio Periodo (en días) donde el password debe ser cambiado.
5. Dias despues del cambio En los días después donde debe ser cambiado.
6. Tiempo del aviso Periodo en el que el sistema tiene que avisar de la necesidad del
cambio.
7. Inhabilitación Días antes de la inhabilitacion de la cuenta.
8. Perido caducado Días desde el 1 de enero de 1970 en el que la cuenta está deshabilitada.
9. Campo reservado
Bien ahora, ya que conocemos la estructura de los archivos, creemos un nuevo usuario, sólo
tendremos que usar un editor, que por razones de seguridad son vipw para el archivo /etc/passwd
y vigr para editar /etc/group; ambos usan como editor el que esté en la variable $EDITOR del
sistema, y passwd para crear el password. Sigamos los siguientes pasos:
1. Lo primero es entrar como root
$ su -
password:
# vipw /etc/passwd
2. Editamos el fichero /etc/passwd, ahí estarán las lineas de otros usuarios que ya estén
creados. Esto que sigue es un ejemplo.
prueba:x:1005:1005::/home/prueba:/bin/bash
Hemos escrito un nombre cualquiera (prueba), el password le ponemos x dado que es un sistema
con shadow. Si queremos crear una cuenta sin contraseña, en este campo en vez de la x no pondremos
nada. ADVERTENCIA: Esto es un considerable riesgo de seguridad. Incluso una cuenta de usuario
puede usarse para hallar información útil para posteriormente poder atacar un sistema.
3. Ahora hay que tocar en /etc/group para crear el grupo del usuario (todo usuario tiene un
grupo principal), le damos el mismo nombre que al usuario, y el GID que hemos puesto antes, el 1005.
Por supuesto, tanto los UID como los GID no pueden estar repetidos, así que nos aseguramos de coger
uno que no esté ya cogido. Entonces, hacemos:
# vigr /etc/group
prueba:x:1005:
11
Administración de Sistemas Linux Comandos Básicos de Linux
4. Editamos /etc/shadow:
prueba:!:1[Link]
5. Bueno lo peor será calcular la fecha de creación pero sino randomized(). Notese que en el campo
password le hemos puesto ! porque ahora le daremos un password con passwd.
# passwd prueba ##Ejecutamos passwd y pasamos el nombre del usuario como argumento.
Enter new UNIX password: ##Introducimos el password para ese usuario, hay que
##darse cuenta de que a medida que escribimos, por razones obvias de seguridad no
##se irá escribiendo nada.
Retype new UNIX password: ##Repetimos la password
6. Ahora le tenemos que crear el directorio de trabajo, por convenio los directorios de trabajo de los
usuarios normales están bajo /home, y suelen ser /home/usuario.
# mkdir /home/prueba
7. Copiamos los archivos de inicio desde /etc/skel , que contiene principalmente archivos de
configuración por defecto
# cp /etc/skel/.* /home/prueba
8. Y por último, hay que hacer que tome posesión de lo que es suyo:
# chown [Link] -R /home/prueba
Ahora solo falta logearse con el usuario prueba, bien utilizando el comando su o un haciendo
login directamente en un shell del sistema:
# su - prueba
prueba@maquina:/home/prueba$
Comandos de Administración de Usuarios
Estos comandos nos permitirán crear, borrar y modificar las cuentas de usuarios en el sistema.
adduser y useradd son dos comandos que hacen prácticamente lo mismo. Nota que el estándar es
useradd, adduser puede, en algunas distribuciones ser un simple enlace a useradd, o simplemente no
existir. El comportamiento por defecto de useradd es muy subjetivo dependiendo de la distribución
de Linux que estemos usando. Así, mientras que en algunas distribuciones hará casi todos los pasos
anteriores por nosotros, en otras sólo añadirá el usuario a /etc/password y /etc/shadow,
teniendo que realizar nosotros los pasos restantes. Aun así, las opciones que recibe useradd responden
igual en todas las distros. Como ya hemos hecho con algún otro comando, puedes ver las opciones de
useradd mediante man useradd, moverte con las teclas de dirección y volver al shell pulsando la
tecla Q.
Las opciones más comunes para useradd son:
# useradd -g users -d /home/usuario -s /bin/bash -m -k /etc/skel usuario
12
Administración de Sistemas Linux Comandos Básicos de Linux
• -d Establece el que será el directorio de trabajo del usuario, por convenio para usuarios
normales, es /home/nombre_de_usuario
• -s Es la shell por defecto que podrá usar el usuario después de hacer login. Lo normal es que
sea /bin/bash, esto es, el shell bash.
• -m -k Estas dos opciones se complementan. La primera, hace que se cree el directorio de
trabajo del usuario en el caso de que este no exista. La segunda, copia los ficheros del directorio
especificado al que se ha creado del usuario.
• usuario Por último, usuario es el nombre del usuario que estamos creando.
• G Aunque esta opción no está en el comando de ejemplo que hemos puesto arriba, es muy útil,
puesto que permite especificar la lista de grupos a la que también pertenecerá el usuario aparte
del grupo principal. Por ejemplo -G audio,cdrom,dip añadido en el comando anterior
haría que usuario perteneciese a estos grupos además de al suyo principal.
Siempre podemos matizar detalles en la creación de usuarios editando los ficheros de
configuración que ya conocemos.
La cuenta del usuario no estará activada hasta que no le asignemos un password. Esto lo
podemos hacer vía password nombre_de_usuario (para cambiar el password procederíamos
exactamente de la misma forma). Cualquier usuario normal puede cambiar su password cuando haya
entrado al sistema, bastando en este caso con escribir el comando password sin argumentos ni
opciones.
Para desactivar una cuenta de usuario sin necesidad de borrala del sistema, podemos editar
/etc/passwd y cambiar la x por un ! en el campo del password. La cuenta se habilitaría asignando
un password con password o bien volviendo a poner la x que había, quedando la cuenta entonces con
el mismo password que tenía antes de deshabilitarla.
Podríamos, si nuestra distro dispone de ellas, utilizar las herramientas interactivas para crear
usuarios (a traves de Yast, solo accesibles por root). Aunque pueden resultar más cómodas, siempre es
conveniente saber el método general de creación de usuarios, de tal forma que esos conocimientos nos
servirán para cualquier distribución de Linux que vayamos a usar.
En algún momento podríamos necesitar editar una cuenta de usuario creada, o borrarla. Existen
también comandos de administración estándares para esto; son usermod y userdel. Puedes ver sus
páginas del manual con man. Aunque, una vez más, editando los ficheros de configuración no
necesitarás memorizar opciones para efectuar esos cambios.
El comando whoami muestra el nombre de usuario que está dentro del sistema usando el shell
desde el que se le llama.
Administración de Grupos
En la administración de grupos no vamos a gastar muchas energías ya que no es, en un nivel
básico, algo excesivamente complejo.
13
Administración de Sistemas Linux Comandos Básicos de Linux
privilegios a un conjunto de usuarios sin tener que dárselo de forma indivial a cada uno.
El fichero encargado de mantener los grupos del sistema es /etc/group y también hemos visto su
estructura. Por lo que veremos los comandos que añaden, quitan y modifican los grupos; así como
notas generales en la gestión de grupos.
Hemos dicho que todo usuario tiene siempre un grupo principal al que pertenece. Hay dos
posibilidades para los usuarios normales: que todos tengan el mismo grupo principal (generalmente
users) o que cada usuario tenga un grupo principal específico (casi siempre del mismo nombre que el
usuario). Esto responde a las necesidades de cada sistema. En el primer caso, los directorios de trabajo
de los usuarios suelen ser accesibles por el resto de usuarios (no es lo más común); mientras que en el
caso de que cada usuario tenga un grupo principal, lo normal es que los directorios de trabajo de cada
usuario sean sólo accesibles por ese usuario (que sí es lo más común).
La utilidad del grupo principal de un usuario se entenderá mejor cuando lleguemos a los
permisos.
Además, en el sistema hay más grupos que los principales de cada usuario. La misión de estos
otros grupos es la de otorgar unos permisos similares al conjunto de usuarios que forman parte de él
ante un directorio, un archivo, un dispositivo, etc.
Es muy común la necesidad de dar a unos cuantos usuarios permisos para que puedan, por
ejemplo, leer los documentos de un directorio determinado (por ejemplo, informes de una empresa), al
tiempo que al resto de usuarios no. Así, podríamos crear un grupo llamado contables, y agregar los
usuarios que son contables a este grupo. Después, haríamos pertenecer (como veremos en Permisos) el
directorio mencionado a este grupo, y le daríamos permisos de lectura para el grupo.
Además de para compartir archivos o directorios entre varios usuarios, existen grupos como
audio, cdrom, y similares. Dispositivos como la tarjeta de sonido, el grabador de CDs, etc. tienen
como usuario "dueño" a root, y como grupo "dueño" a uno de estos grupos. Así, para cada usuario que
queramos que pueda usar la tarjeta de sonido, debemos añadirlo al grupo audio.
Ya hemos aprendido cómo establecer el grupo principal de un usuario, y cómo hacer a la hora
de su creación que pertenezca a otros grupos adicionales; así como el fichero /etc/group. Así que
ya no queda mucho en este aspecto.
Para añadir un usuario a un grupo de forma manual, todo lo que hay que hacer es editar
/etc/group y añadir al usuario a la lista del último campo. Si ya hay usuarios, éstos se separan con
comas.
Si lo que queremos es crear un nuevo grupo de forma manual, la cosa es igual de sencilla. Al
igual que ya hicimos agregando el usuario prueba de forma manual, añadiremos otra entrada a este
fichero con el nombre del grupo, la x en el password, un GID que no esté siendo usado y la lista de
usuarios detrás.
14
Administración de Sistemas Linux Comandos Básicos de Linux
También tenemos comandos que hacen esto mismo: groupadd , groupdel y groupmod.
groupadd sirve para crear un nuevo grupo:
# groupadd -g gid grupo
Lo mismo que sabemos ya sobre la edicición y borrado de usuarios es aplicable a los grupos. Lo
más fácil es editar el fichero /etc/group directamente; recordando que si quitamos un grupo,
ningún usuario podrá tener ese grupo como su grupo principal; y además que tendremos que cambiar
los permisos (después más en esto) de los archivos que perteneciesen a este grupo pues de no hacerlo
los estaríamos dejando asignados a un GID inexistente para el sistema, y esto no es recomendable.
Un comando curioso es groups, que mostrará una lista de grupos a los que el usuario actual
pertenece.
Permisos
Todos y cada uno de los elementos del sistema / de Linux tienen dueño, ya sean ficheros,
directorios, o enlaces a dispositivos. Por un lado, tienen un usuario dueño, y por otro, un grupo dueño.
El usuario y el grupo que son dueños de un elemento no tienen por qué guardar una relación del tipo
que el usuario debería estar dentro del grupo o cosas por el estilo. Son totalmente independientes. Así,
puede existir un fichero que tenga como usuario propietario a username, un usuario normal, y tener
como grupo propietario al grupo root.
Cuando se trabaja en el sistema, los programas "hacen dueños" de los ficheros creados durante
la sesión al usuario de esta sesión y a su grupo principal por defecto; aunque esto puede cambiarse. Es
lógico, que los ficheros que estén bajo el directorio de trabajo de un usuario le pertenezcan.
Siempre que tratemos con permisos y con dueños de elementos, debemos tener siempre presente
el hecho de que el sistema de ficheros de Linux es jerárquico; esto implica que los cambios que
hagamos, por ejemplo, en un directorio, pueden influir en el resto de elementos que están contenidos en
un nivel inferior a éste (los archivos que contiene, los directorios que contiene, lo que contienen esos
otros directorios, y así sucesivamente).
El comando chown (CHange OWNer cambiar propietario) permite cambiar el propietario de
los elementos del sistema de archivos. Pero es lógico que si somos un usuario normal no podremos
cambiar de propietario los elementos que pertenecen a root o a otros usuarios. En cambio, como root
podremos cambiar el propietario de cualquier cosa. Aquí describimos las opciones más usadas de este
comando, pero puedes ir mirando su página del manual del sistema.
15
Administración de Sistemas Linux Comandos Básicos de Linux
En el primero de los dos comandos anteriores, el usuario dueño de elementos(s) será cambiado a
usuario. El grupo dueño de elemento(s) se conservará el que estuviera antes de introducir este coman
do.
Con respecto al segundo comando, actúa exactamente igual que el anterior, con la pequeña dife
rencia que también cambiará el grupo dueño de elemento(s) pasando a ser grupo. Si sólo queremos
cambiar el grupo de un elemento o lista de ellos, podemos usar el comando chgrp.
# chgrp grupo elemento(s)
elemento(s) puede ser una lista de archivos y directorios, o simplemente uno de ellos. Podemos usar los
wildcards conocidos (como por ejemplo el asterisco: * para indicar varios archivos con una sola
expresión. La importante opción -R permite cambiar dueños de directorios y de todo lo que tengan
debajo, es decir, recursivamente:
# chown -R [Link] directorio/
Una buena asignación de dueños de elementos junto con una política adecuada de permisos
sobre estos elementos, permiten obtener dos cosas: un sistema multiusuario, y un sistema seguro.
Si haces un ls -l en un directorio que tenga algunas cosas verás algo como:
$ ls -la bin/
drwxr-xr-x 2 root root 4096 Apr 16 17:19 .
drwxr-xr-x 21 root root 4096 May 23 20:34 ..
-rwxr-xr-x 1 root root 2872 Jun 24 2002
arch-rwxr-xr-x 1 root root 94364 Jun 25 2001 ash
-rwxr-xr-x 1 root root 472492 Jun 25 2001 [Link]
-rwxr-xr-x 1 root root 10524 Jul 19 2001 aumix-minimal
lrwxrwxrwx 1 root root 4 Feb 4 2002 awk -> gawk
En el campo de la izquierda Podemos ver como cuatro grupos. El primero es de un caracter
solamente. Este caracter es una d si el elemento listado es un directorio, una l si el elemento es un
enlace, y un guión - si el elemento es un archivo normal.
A continuación hay tres grupos. Cada uno de estos grupos tiene tres letras, pudiendo ser estas
16
Administración de Sistemas Linux Comandos Básicos de Linux
rwx o pudiendo ser sustituidas en algún caso por un guión. El primero de estos grupos indica los
permisos que tiene sobre el elemento listado su usuario dueño; el segundo grupo indica los permisos
que tienen sobre el elemento los usuarios que pertenezcan al grupo dueño, y el tercer grupo indica los
permisos que tienen sobre el elemento el resto de usuarios del sistema.
La opción R es opcional, y cumple exactamente la misma función que en el comando chown. A
B y C son un número de una cifra respectivamente. El primer número representa los permisos que
estamos asignando al usuario dueño , el segundo los del grupo dueño, y el tercero los del resto de
usuarios. Cada una de las cifras posibles corresponde con los permisos del usuario en binario; aunque
es más fácil aprenderse qué hace cada cifra que pasar la cifra a binario cada vez que queramos cambiar
los permisos a algo. Algunos ejemplos:
• El 4 en binario es 100, por tanto, los permisos que otorga son r--, esto es, sólo lectura.
• El 5 en binario es 101, por tanto, los permisos que otorga son r-x, lectura y ejecución.
• El 6 en binario es 110, por tanto, los permisos que otorga son rw-, lectura y escritura.
• El 7 en binario es 111, por tanto, los permisos que otorga son rwx, lectura, escritura y ejecución.
Los permisos de ejecución sólo se otorgarán a programas o scripts (con los que trataremos
después); ya que hacerlo a los archivos normales carece por completo de sentido. Así, un comando de
ejemplo podría ser:
$ chmod 640 mitexto
Este comando asignaría permisos de lectura y de escritura al usuario propietario, y permisos de
lectura a los usuarios del grupo dueño, y ningún permiso al resto de usuarios para el archivo mitexto.
Puedes ir haciendo pruebas combinando los distintos números y ver los permisos que otorgan mediante
ls -l. Recuerda que los directorios que quieras que puedan ser "examinados", debe tener permisos de
"ejecución" por parte de los usuarios que quieras que puedan acceder a ellos, por ejemplo podrías
asignarlos con el número 5. A los que además quieras que puedan crear archivos en ese directorio,
podrías darle esos permisos mediante el número 7. Con la opción -R puedes hacer que los permisos se
asignen de modo recursivo a un directorio y a todo lo que hay debajo de él.
Un modo muy común para los directorios que deban ser accesibles por todo el mundo es 755, de
forma que el usuario dueño pueda además escribir. Los directorios /home/usuario suelen tener
permisos 750 para que el resto de usuarios no puedan acceder al directorio de trabajo de un usuario.
Un modo muy común de añadir permisos de ejecución a un archivo (generalmente un script)
para todos los usuarios del sistema, sin tener que estar recordando qué números otorgan permisos de
ejecución, es usar la opción +x de chmod, por ejemplo:
17
Administración de Sistemas Linux Comandos Básicos de Linux
$ chmod +x mi_script.sh
Esta forma de asignar permisos es extensible, y según los casos, más sencilla que la de los
números. En general es así:
$ chmod ABC fichero
• Donde A es u (usuario), g (grupo) o bien a (todos). Cuando es a, se puede omitir.
• B es + o bien - , indicando el primero añadir un cierto permiso y el segundo quitarlo.
• C es r (lectura), w (escritura) o bien x (ejecución).
Ejemplos:
$ chmod g+w fichero
$ chmod -r fichero
$ chmod u+x fichero
El primer comando otorga permisos de escritura sobre fichero a los usuarios del grupo al que
el fichero pertenece.
El segundo comando elimina los permisos de lectura sobre fichero a todo el mundo.
El tercer comando da al usuario dueño de fichero permisos de ejecución.
18
Administración de Sistemas Linux Comandos Básicos de Linux
El Editor VIM
Conceptos Básicos
A lo largo de la administración de un sistema Linux podemos toparnos con la necesidad de
editar un fichero de configuración o algo parecido. Bien, en Linux hay muchos editores que pueden
satisfacer nuestras necesidades (nano, pico, joe, jedit...). Mostraremos un editor muy potente y
queremos que con estas nociones cualquier usuario pueda beneficiarse de la potencia de VIM sin tener
que entrar en muchos detalles ni en cosas complicadas.
Antes de nada vamos a introducir un poco sobre qué es VIM, de dónde viene y qué vamos a
aprender.
VIM es un editor de textos para Linux. Es un derivado de VI, VIM significa VI iMproved, es
decir, el mismo editor VI pero mejorado. Y en este capítulo aprenderemos a hacer un uso básico de este
fabuloso editor.
Funcionamiento de VIM
VIM tiene dos grandes modos para funcionar, el modo de edición y el modo comandos. Para
pasar del modo comandos (que es en el que se inicia VIM) al modo edición, pulsamos la tecla I o
Insert. Para pasar del modo edición al modo comandos pulsaremos la tecla Esc.
Para iniciar VIM, haremos lo siguiente:
$ vim <fichero>
Modo Edición: Este es el modo en el que podremos editar un texto, o crear uno nuevo... Si pulsamos la
tecla I o Insert otra vez cambiaremos el modo Insert por el modo Replace. No creo que haya que expli
car mucho las diferencias entre insertar texto o reemplazar el texto. Para movernos por el fichero pode
mos utilzar las flechas,Re.Pág y Av.Pág.
Modo Comandos: Este es el modo mas interesante de VIM, con él podemos hacer cosas muy curiosas,
como por ejemplo, activar el resaltado de sintaxis, deshacer, abrir un nuevo fichero, guardar, etc.
En la siguiente tabla se explican los comandos que pueden resultar más interesantes.
19
Administración de Sistemas Linux Comandos Básicos de Linux
Modo Especial Visual: Para entrar a este modo tenemos que pulsar v en el modo comandos. Para salir
de el pulsaremos Esc.
El modo VISUAL nos permitirá eliminar grandes bloques de texto sin tener que ir borrando
línea a línea. Para ello entraremos en el modo VISUAL (pulsando v) y nos moveremos con los cursores
para seleccionar el bloque que queremos eliminar. Una vez tenemos seleccionado el bloque, pulsamos
Supr y ya está, VIM nos informará de que hemos eliminado un bloque de "n" líneas.
El fichero ~/.vimrc
Vim cuenta con un fichero de configuración en ~/.vimrc que nos puede ser muy útil para
personalizar nuestro VIM. Cualquier comando de VIM se puede introducir en él. Además de esto, hay
muchas opciones que pueden cambiarse y hasta sentencias. Cualquier línea que comience con
" (comillas) será ignorada por VIM. A esto lo llamamos comentarios.
Obtener Ayuda
Obviamente esta ha sido una introducción muy liviana a Vim. Pero ¡VIM es mucho más!. Y el
mejor punto de partida es ejecutar vimtutor. Este comando lo que hace es ir guiándonos paso a paso y
con ejemplos. Editando buffers (ficheros) preparados para el correcto aprendizaje de vim. Vim es muy
grande, se pueden hacer muchas cosas con él. Es muy recomendable utilizar vimtutor para iniciarse en
este gran editor.
20
Administración de Sistemas Linux Comandos Básicos de Linux
Entrada y Salida
Introducción a los conceptos de entrada y salida
Cuando estamos dentro del sistema usando la terminal bash, generalmente tecleamos comandos
para que sean ejecutados. El hecho de que estemos simplemente presionando el teclado implica que
estamos entrando datos al sistema mediante el teclado. Cuando en ejemplos anteriores hemos usado el
comando ls, ha aparecido en pantalla un listado de archivos y directorios, claramente el sistema ha
producido salida de datos mediante el monitor.
Hemos puesto dos ejemplos, el teclado como vía para entrar datos al sistema (o bien a un
programa, como ya vimos con vim), y el monitor como vía de salida de los datos. Pero no son, ni
mucho menos, las únicas posibilidades. Los distintos puertos físicos del ordenador pueden ser vía de
entrada o de salida de datos, igualmente con la tarjeta de sonido, módem, tarjeta de red.
Los sistemas UNIX (y por ello también los Linux), son especialmente conocidos por su
facilidad y eficiencia para pasar datos entre programas y programas o entre programas y dispositivos,
siendo esta una de sus múltiples ventajas.
Otros conceptos importantes dentro de estos son los de entrada estándar y salida estándar (st
din y stdout respectivamente). Por defecto, stdin apunta al teclado (los datos, se toman generalmente
por defecto del teclado), y stdout apunta a la pantalla (por defecto los programas suelen enviar la salida
por pantalla).
Comandos principales asociados con la salida
Son, principalmente echo, cat. En primer lugar, echemos un vistazo al comando echo. Este comando
nos permite "imprimir" cosas en la pantalla.
Veamos algunos ejemplos:
usuario@maquina ~ $ echo "Hola, usuario de Linux"
Hola, usuario de Linux
Como ves, por defecto el comando echo recibe las cadenas de texto entre comillas (simples o
dobles), y saca por defecto a la pantalla lo que le pasamos como argumento; aunque puede enviar la
salida a otros sitios, como podrás comprobar más adelante.
El shell puede hacer operaciones aritméticas básicas, y podemos aprovecharlas con el comando echo:
usuario@maquina ~ $ echo $[5*3]
15
21
Administración de Sistemas Linux Comandos Básicos de Linux
usuario@maquina ~ $ cat
Escribo esto
Escribo esto
Y escribo esto otro
Y escribo esto otro
Este es el uso más frecuente para el comando cat, tomar como entrada un fichero y sacar su
contenido por la salida. Por defecto es por la pantalla, pero descubriremos después que puede enviar el
contenido de un fichero por otras vías.
Como ya habrás imaginado, los ficheros de disco pueden ser objeto de entrada (leer su
contenido) o de salida (escribir la salida de un determinado comando a un fichero). El comando
siguiente, touch nos da la posibilidad de crear un fichero vacío con el nombre que nosotros le
especifiquemos:
usuario@maquina ~ $ touch minuevofichero
Así crearemos un fichero nuevo vacío al que podremos posteriormente enviar la salida de
nuestros comandos. Si listas el fichero con ls -l minuevofichero verás como efectivamente su
tamaño es cero.
Pipes o tuberías
Hasta ahora hemos estado practicando de dónde toman los datos algunas de las utilidades más
comunes, y hacia dónde envían su salida. Lo siguiente que tenemos que plantearnos sería... ¿no
podríamos "conectar" de alguna forma la salida de un programa y hacer que otro programa lea de ella?
Efectivamente, podemos conseguir esto. El caracter | nos permite crear estas conexiones entre
programas en el shell. Ejemplo:
22
Administración de Sistemas Linux Comandos Básicos de Linux
Lo que este comando hará será lo siguiente: La primera parte antes de la barra vertical,
conseguirá el contenido del fichero mifichero, y con la barra vertical, en lugar de sacarlo por la
pantalla, lo enviará a la entrada estándar (stdin) de tal forma que el programa grep leerá desde stdin el
contenido del fichero mifichero. El concepto del efecto que esto produce es fácil de entender: el
comando que va detrás de la barra lee de la salida que dió el comando anterior. Es obvio que lo que
obtendremos serán las líneas del fichero mifichero que contienen la palabra "gato" por la pantalla
(stdout).
Como ves, no estamos pasando ninguna opción ni al comando cat ni al comando grep. Esto es
porque el primero (cat) envía la salida por defecto a stdout, y grep, si recuerdas, lee por defecto de stdin
(que al usar la barra vertical, hemos hecho que stdin sea la salida del primer comando y no las líneas
que tecleemos a continuación como hicimos anteriormente). Pero los pipes con la barra vertical
podremos emplearlos con otros programas que no tengan este comportamiento por defecto, esto es, que
su salida no apunte por defecto a stdout (podría apuntar, por ejemplo, a un fichero) o que no lean por
defecto de stdin. Podremos hacer que tengan este comportamiento pasándoles determinadas opciones si
disponen de ellas. Es muy común la opción - (un solo guión) para hacer que un programa lea de stdin o
escriba a stdout si tiene esta funcionalidad.
Otros caracteres que nos permiten crear "pipes", son < y >. Generalmente, este par de caracter
trabajan con un fichero a un lado y un comando a otro. veamos primero el caracter <:
$ grep gato < mifichero
Esta línea es equivalente a la del ejemplo anterior. El contenido del fichero que ponemos a la
derecha del signo se va a la entrada estándar de la que lee el comando que ponemos a su izquierda, por
lo tanto esta línea conseguiría exactamente el mismo efecto que la del ejemplo anterior.
Ahora el signo contrario. A la izquierda del signo > ponemos un comando, y a la derecha el
nombre del fichero al que queremos que se escriba la salida del comando. Por ejemplo:
$ ls -la > listado
La lista del contenido del directorio actual que el comando ls sacaría normalmente por pantalla,
en vez de eso se ha escrito en el fichero listado. Si el fichero no existía, se ha creado, y si existía y
tenía contenido, ha sido sobreescrito, asi que tengamos cuidado.
La lista del contenido del directorio actual que el comando ls sacaría normalmente por pantalla,
en vez de eso se ha escrito en el fichero listado. Si el fichero no existía, se ha creado, y si existía y
tenía contenido, ha sido sobreescrito, asi que tengamos cuidado.
$ echo "Esta es otra línea" >> texto
Vemos en qué es similar a lo anterior; la línea "Esta es otra línea se ha escrito al fichero texto.
Si el fichero no existía, ha sido creado, y la diferencia, si existía y tenía contenido, la línea se ha escrito
23
Administración de Sistemas Linux Comandos Básicos de Linux
al final del fichero, debajo del contenido que ya tenía. Este comportamiento nos puede ser muy útil de
cara a ir añadiendo líneas a un archivo sin necesidad de tener que abrirlo con un editor.
Otras utilidades y detalles de la E/S en el shell
Vamos a ver cómo la entrada estándar, la salida estándar y alguna cosa más "están" en el sistema
de archivos.
La entrada estándar (stdin) está enlazada mediante el dispositivo (sobre lo que se hablará más
adelante) /dev/stdin:
$ echo "hola" | cat /dev/stdin
hola
Con el comando echo, escribimos la palabra "hola" a la salida estándar, que con la barra
vertical, se pasa a la entrada estándar, pero como le estamos pasando un argumento a cat, lee de
/dev/stdin que... ¡sorpresa! ha resultado ser la entrada estándar. Si hubiesemos escrito el mismo
comando quitando /dev/stdin, el resultado habría sido el mismo, puesto que si a cat no le pasamos
ningún argumento, lee desde stdin. No te preocupes si no puedes comprender del todo lo que hace este
ejemplo, simplemente tú asocia /dev/stdin con la entrada estándar que es accesible desde el sistema
de ficheros
La salida estándar está asociada a /dev/stdout:
$ cat fichero > /dev/stdout
--contenido de fichero--
Aquí, estamos enviando el contenido de fichero a /dev/stdout que, curiosamente, igual que
en el caso anterior, ha resultado "conectar" con la salida estándar, esto es, la pantalla.
Por último, presentaremos a nuestro basurero particular, que es /dev/null. Nos puede ser útil
para cuando queramos despreciar la salida de un comando, que ni salga por pantalla ni que se quede es
crito en un fichero, simplemente que se pierda:
$ cat mimayorfichero > /dev/null
Una ventaja de /dev/null con respecto a los basureros físicos es que nunca se llena ;) , podemos
"arrojarle" toda salida que queramos despreciar.
Comandos more y less
more y less son dos comandos útiles a la hora de paginar. Paginar es ver un archivo o una sali
da larga por partes (o páginas), puesto que de otra forma sólo podríamos ver el final de esta salida lar
ga. Pongamos por ejemplo que quisiésemos leer un archivo largo. Como ya sabes, esto podrías hacerlo
con el editor vim, pero también podrías hacerlo con cat y la ayuda de estos dos comandos:
$ cat archivolargo | more
$ more < archivolargo
$ more archivolargo
24
Administración de Sistemas Linux Comandos Básicos de Linux
Como ya sabemos, los dos primeros comandos son exactamente equivalentes. Pero el tercero
tiene una pequeña diferencia con respecto a los anteriores. Si introducimos uno de los dos primeros con
un archivo largo, entonces veremos que el programa more nos indica en la parte inferior "Más" o
"More", y nada más; mientras que si introducimos el tercer comando, en la parte inferior de la terminal
nos aparecerá "More (15%)", esto es, el porcentaje del fichero que estamos mostrando. La diferencia
pues entre estos comandos es que en los dos primeros, more no conoce la longitud de los datos que
vienen por la stdin, simplemente los procesa conforme el usuario se lo pide; mientras que en el tercer
caso, el funcionamiento de more es conocer la longitud del fichero que se le pasa como primer
argumento, y después paginarlo igual que hacía con los datos de stdin. Esto es importante; en UNIX y
en Linux podemos trabajar con la stdin y stdout conforme vayamos necesitando sus datos, sin necesidad
de saber cuál es su longitud o sin miedo de que estos vayan a perderse.
En lo que respecta al comando more, podemos seguir paginando hacia abajo con la barra
espaciadora, hasta llegar al final del fichero o de los datos de entrada; o bien presionar la tecla q en
cualquier momento para abandonar el programa.
Frente a more, less nos ofrece algunos comandos que nos ayudan a buscar cadenas y patrones dentro
del buffer que less esté visualizando. En la siguiente tabla se muestran las opciones mas usadas del
comando less:
Comando Descripción Ejemplo de uso si aplica
:n Examina el siguiente fichero en la lista de argumentos de less --
:p Examina el fichero anterior en la lista de argumentos de less --
:e fichero Examina el fichero pasado como argumento :e /etc/xml/docbook/cata
log
:x N Examina el primer fichero de la lista si N no ha sido especifi :x 6
cado, en caso contrario examina el fichero que esté en la posi
ción N de la lista.
:d Elimina el fichero que se está examinando de la lista --
= o ^G o Da información adicional sobre el fichero incluyendo el nom =
^F bre, el número de línea el %...
!comando Nos permite ejecutar el comando como si estuvieramos en una !xmllint --valid --noout %
shell. !! ejecutará el último comando ejecutado. Si se incluye
en el comando el símbolo % será reemplazado por el fichero
que se está examinando en ese momento, y # por el ultimo fi
chero examinado. Si no se especifica un comando devolverá
una shell que se tomará de la variable de entorno SHELL.
/patrón Se busca en el fichero la cadena especificada por patrón. Si no /*gfdl
se especifica ningun patrón se utilizará el último patrón busca
do. Si el primer caracter de patrón es un * se buscará el patrón
25
Administración de Sistemas Linux Comandos Básicos de Linux
Recuerda que puedes utilizar more y less con otros comandos distintos que produzcan mucha
salida, y usarlos para ver la salida detalladamente.
Otro pequeño truco, es que si estás en una terminal, puedes ver las líneas anteriores (que ya no
se muestran en pantalla) manteniendo pulsada la tecla de las mayúsculas (no el bloqueo de mayúsculas)
y a continuación presionando las teclas "avanzar página" y "retrocer página" de tu teclado para moverte
por líneas anteriores de tu sesión en una terminal.
Error Estándar stderr y otras redirecciones
Hemos visto stdin y stdout, entrada y salida estándar, respectivamente. Sabemos que el siguiente
ejemplo listará los contenidos del directorio actual y despreciará ese listado, enviándolo a /dev/null:
$ ls ./ > /dev/null
$ ls directorio_inexistente/ > /dev/null
ls: directorio_inexistente: No existe el fichero o el directorio.
En el primer caso, todo fue como esperábamos, la salida del listado fue simplemente
despreciada. Pero... ¿qué ha pasado en el segundo caso? Con el signo > le decíamos que enviase la
salida estándar, en este caso, a /dev/null. Y, aunque no lo parezca, la salida estándar fue a /dev/null. Lo
que ha pasado es que el mensaje de error no ha ido a stdout; porque de haber sido así habría sido
despreciado. ¿Dónde ha ido entonces el mensaje de error? Es sencillo, a stderr. La mayoría de los
programas imprimen stderr por pantalla; aunque podrían (como hacen algunos), escribir los mensajes
de error a un fichero, o por qué no, despreciarlos.
Algunos programas hacen estas cosas con stderr; cosas que ya hemos aprendido nosotros a
hacer con stdout. Una solución posible sería que stderr fuese a stdout, y a partir de ahí, nosotros ya
pudiésemos redirigir stdout como sabemos. Conseguir esto no es difícil, se hace con el operador >& :
$ ls directorio_inexistente/ > /dev/null 2>&1
Ahora sí será despreciada stderr; pero analicemos este comando por partes, y entendámoslo
bien. Debemos saber que en él, "2" representa a stderr, y que "1" representa a stdout. Más cosas; este
comando tiene dos partes. La primera es ls directorio_inexistente/ > /dev/null y la segunda
es 2>&1. En las redirecciones de salida complejas, como es esta, el shell las interpreta "al revés", esto
es, de derecha a izquierda. Primero interpreta lo que hemos dicho que es el segundo comando, y luego
interpreta el primero. Lo que ocurre entonces es lo siguiente: primero, stderr va a stdout por el segundo
comando que se procesa en primer lugar, y luego stdout (que ya "contiene" a stderr) se va a /dev/null.
Entonces conseguimos el efecto deseado, despreciar tanto stdout como stderr; aunque podríamos haber
hecho otras cosas con ellas, lo importante es que ambas "salidas" habrían ido al mismo sitio.
26
Administración de Sistemas Linux Comandos Básicos de Linux
Pero puede ocurrir el caso en que se desee tratar por separado stdout y stderr. Si se entendió el
ejemplo anterior esto no debería causar problemas. Vamos a poner, como caso práctico, que vamos a
listar una serie de archivos o directorios; los que existan se escribirán sus detalles en un fichero, y los
que no obtendremos el error en otro fichero distinto:
$ ls -l fichero1 fichero2 fichero3 > existentes 2>inexistentes
$ ls -l fichero1 fichero2 fichero3 1>existentes 2>inexistentes
Estos dos comandos son absolutamente equivalentes. Recordemos que este tipo de comandos
son interpretados de derecha a izquierda. En el primero de ellos, al principio stderr se escribirá al
fichero inexistentes, y después el resto (o sea, stdout) se escribirá al fichero existentes. En el segundo,
primero 2 (stderr) se escribirá a inexistentes, y después 1 (stdout) se escribirá a existentes. Usando
cualquiera de ellos, al final tendremos en el fichero existentes los detalles de los ficheros existentes y
en el fichero inexistentes el error producido por los ficheros (o directorios) que no existen. Este
ejemplo es bastante ilustrativo de cómo podemos tratar separadamente stderr y stdout.
27
Administración de Sistemas Linux Comandos Básicos de Linux
Introducción al Shell Scripting
Los scripts de shell nos dan la posibilidad de automatizar series de comandos y evaluciones de
condiciones. Un script es como se llama a un archivo (o conjunto de archivos) que contiene
instrucciones (en nuestro caso comandos de bash), y que necesita de un programa ayudante para
ejecutarse (en nuestro caso la propia terminal bash será el programa ayudante). Un script tiene cierta
similitud con un programa, pero existen diferencias. Generalmente, los programas están en lenguaje de
máquina (la máquina lo entiende directamente), mientras que los scripts son archivos que contienen en
formato texto los comandos o instrucciones que la aplicación ayudante ejecutará.
Primer Script en Bash
Llegados a este apartado ya se debe tener buena practica con bash y con el editor vim, ya se
debe estar preparado para crear un primer script bash. Si recordamos, un script era un archivo de texto
plano con comandos; así que haz vim [Link] y pon en él lo siguiente (lo explicaremos detenida
mente a continuación):
#!/bin/bash
echo "Hola"
echo "Este es mi primer Script en Shell."
Como ya sabemos, la extensión en los archivos en Linux no tiene significado útil. Es por
convenio general, por lo que a los scripts de shell se les llama con la extensión ".sh" (de SHell). De este
modo identificaremos fácilmente nuestros scripts entre el resto de archivos de un directorio.
Observemos la primera línea: #!/bin/bash. Esta línea es un tanto especial, y es característica
de todos los scripts en Linux, no solamente los de bash. Tras #! indicamos la ruta a la aplicación
ayudante, la que interpretará los comandos del archivo. En nuestro caso es bash, así que ponemos ahí
/bin/bash, que es la ruta hacia la aplicación bash.
Se puede ver, que no importa que pongamos líneas en blanco, pues serán ignoradas. Podemos
ponerlas después de cada bloque de comandos que tengan cierta relación, para dar claridad y
legibilidad al conjunto de comandos del script.
Las dos siguientes líneas comienzan por el carácter #. En los scripts de bash, las líneas que
comienzan con este signo son ignoradas, y se llaman comentarios. Podemos usarlas para explicar qué
hace el grupo de comandos siguiente, de tal forma que cuando editemos el script en el futuro nos sea
más fácil descubrir qué es lo que está haciendo en cada sitio; o podemos usarlos para dar cualquier otra
información importante de cara a la edición del archivo.
Las dos últimas líneas son dos comandos, de los que luego serán ejecutados por bash. Como
sabemos, el comando echo saca por stdout (por defecto por pantalla) lo que le pasemos como
argumento, en este caso dos frases. Podemos añadir cualquier comando normal de los que hemos visto,
que será ejecutado normalmente. Después escribiremos algunos scripts más complejos, para que te
28
Administración de Sistemas Linux Comandos Básicos de Linux
hagas una idea de para cuánto pueden servirnos.
Guardemos el script y salgamos de vim. Ahora lo ejecutaremos. La primera forma de hacerlo es como
sigue:
$ bash [Link]
Hola
Este es mi primer Script en Shell.
Al darle permisos de ejecución, podemos ejecutar ahora nuestro script como si de un programa
normal se tratase. Esto es posible gracias a la primera línea del script, que hace que se llame
inmediatamente a la aplicación ayudante para procesar los comandos. Hemos podido observar que a
nivel del shell, nuestro script es un programa como otro cualquiera, que podemos ejecutar e incluso
ponerlo en algún directorio listado en la variable de entorno $PATH, como por ejemplo
/usr/local/bin y ejecutarlo como si de un programa del sistema se tratase, simplemente tecleando su
nombre.
Variables
Una variable es un nombre al que le hacemos corresponder un valor. Este valor puede ser un
valor numérico o bien una cadena de texto indistintamente en los scripts de shell. Los nombres de las
variables conviene que comiencen por una letra, después veremos por qué.
En el siguiente ejemplo aprenderemos a usar las variables en nuestros scripts:
#!/bin/bash
resultado1=$[5*10/2]
resultado2=$[$variable*$otravariable/$tercera]
exit 0
29
Administración de Sistemas Linux Comandos Básicos de Linux
Repasemos el ejemplo despacio. En primer lugar tenemos la línea que será siempre la primera
en nuestros scripts, y que ya conocemos, la que dice cuál es el programa que ejecutará las instrucciones
del script.
Siguiendo tenemos la asignación de algunas variables, esto es, estamos dando valor a algunas
variables que luego usaremos. Observa que entre el nombre y el valor, NO HAY ESPACIOS, es
variable=valor. Procura recordarlo. Ahora cada variable tiene el valor que le hemos asignado.
Podríamos cambiarlo simplemente de la misma forma, pero poniendo otro valor distinto, que
sobreescribiría a cualquiera que tuviese antes la variable. Así, tercera=7 haría que el valor de la
variable tercera fuese de ahí en adelante 7.
Después nos encontramos con el comando $[ ], que nos permite hacer operaciones
aritméticas, obteniendo el resultado. Después veremos más detenidamente el hecho de que un comando
DEVUELVA un valor. De momento trata de comprender este ejemplo. En la primera de esas líneas, la
variable resultado1 se queda con el valor resultante de efectuar la operación entre los números. En
la línea siguiente, vemos que para REFERIRNOS al valor que tiene una variable, colocamos delante de
su nombre el signo $. Dondequiera que pongamos ese signo delante del nombre de una variable, todo
ello será reemplazado por el valor de la variable. Así, la expresión que se evalúa al final es la misma
que la de la línea anterior, pues todas las variables quedan sustituidas por sus valores reales antes de
que se haga la operación.
En las líneas siguientes usamos el ya conocido comando echo. Es muy conveniente que en
nuestros scripts pongamos entre comillas lo que echo debe sacar por pantalla. Así, en la primera línea
tenemos una forma sencilla posible para generar una línea en blanco en la salida, como podremos
apreciar cuando después ejecutemos el script. Como ves, dentro de las comillas del argumento de
echo, podemos hacer que aparezca el valor de una variable procediendo como ya hemos aprendido.
Atención a la línea siguiente. El comando read va a ser nuestra vía de comunicación con el
usuario en nuestros scripts. Funciona de este modo: primero, ponemos read, el comando que hace
todo el trabajo, y a continuación, ponemos el nombre de la variable donde queremos que la entrada del
usuario quede almacenada (en nuestro caso, la variable es entrada_del_usuario). Cuando a la
hora de ejecutarse, el script llegue a esa línea, esperará a que el usuario escriba algo y presione la tecla
INTRO. En ese momento, lo que el usuario escribió antes de presionar INTRO quedará guardado en la
variable, y luego podremos hacer uso de estos datos que el usuario introdujo, como hacemos en la línea
siguiente, sacarlos de nuevo por pantalla.
Por último tenemos el comando exit. Este comando al final del script no es especialmente útil,
pero si pusiésemos cualquier cosa debajo de él ya no sería ejecutada. Lo usaremos después cuando
30
Administración de Sistemas Linux Comandos Básicos de Linux
queramos que "si se da tal condición, entonces que el programa (script) termine".
Para terminar de comprender mostramos este segundo script de ejemplo, ponerlo en un fichero
llamado, por ejemplo, [Link] con el editor vim. Asignarle permisos de ejecución como
hicimos antes y después ejecútalo:
edison@edison:~/Programas> ./[Link]
El resultado de 5*10/2 es 25 ,
que efectivamente coincide con 25
Comandos Posibles
Una duda que puede surgir es... ¿qué comandos puedo escribir en mis scripts? ¿Tengo alguna
limitación?
De aquí otra de las bondades de los scripts en bash: todos los comandos que escribiremos en
bash pueden escribirse en un script de bash; esto incluye cualquier programa, redirecciones de entrada
o salida, pipes, etc. Usando comandos del sistema, podemos hacer que nuestros scripts hagan casi
cualquier cosa que nosotros queramos, y que se comporten como si de complejísimos programas se
trataran. Esto es, para borrar un fichero dentro de un script, simplemente necesitamos usar el comando
rm, sin preocuparnos por cómo funciona rm internamente. Con los comandos que ahora conocemos,
nuestros scripts podrán: listar ficheros o directorios, borrar, despreciar salidas, buscar en cadenas de
texto, pedir datos al usuario e interpretarlos.
Lo mejor, a parte de conseguir una secuencia automatizada (no será necesario teclear todos los
comandos que necesitemos para una determinada cosa todas las veces; simplemente los escribiremos en
un script y lo ejecutaremos con una sola línea cada vez que lo necesitemos); es que podemos hacer que
los argumentos que le pasemos a un comando en el script sean variables.
Cuando una de nuestras variables sea el argumento de un programa, y si lo llamamos con
muchos argumentos, es muy conveniente para evitar errores extraños, entrecomillar la variable:
MI_VARIABLE=/un/directorio
# No muy adecuado:
ls -l $MI_VARIABLE
# Bastante mejor:
ls -l "$MI_VARIABLE"
Cuidado, en este caso las comillas deben ser dobles.
31
Administración de Sistemas Linux Comandos Básicos de Linux
Comandos Posibles
Cuando un programa termina de ejecutarse, devuelve o retorna un valor. En el caso de los
programas, el valor de retorno es un número. El valor es cero (0) si el programa finalizó con éxito o
distinto de cero si el programa no finalizó con éxito. Cada uno de los valores distintos de cero va
asociado a una causa distinta (sabiendo este valor podríamos saber por qué razón falló el programa),
pero puede que por ahora no lo necesites.
El valor de retorno es un concepto un poco abstracto, pero no es difícil de comprender. El valor
de retorno no se imprime por la pantalla, es decir, cuando un programa termina no saca por pantalla un
cero, pero nosotros podemos saber cuál es ese valor.
En el shell bash (y por extensión, en nuestros scripts) el valor de retorno del último programa o
comando ejecutado queda almacenado en la variable especial $? .
Veamos un ejemplo:
#!/bin/bash
exit
La salida del script anterior es:
edison@edison:~/Programas> ./[Link]
Listando archivo existente...
[Link]
El valor de retorno fue: 0
En el primer caso, pedimos a ls que liste un archivo existente. Lo lista con éxito y por tanto el
valor de retorno vale cero. En el segundo caso le pedimos que liste un archivo inexistente. Como eso no
es posible, el comando no termina con éxito y el valor de retorno es distinto de cero.
La utilidad de conocer el valor de retorno al ejecutar un programa en nuestros scripts salta a la
vista: cuando veamos las sentencias condicionales podremos hacer que el script haga una cosa u otra en
función de si un programa terminó con éxito o no.
32
Administración de Sistemas Linux Comandos Básicos de Linux
Pasar y procesar argumentos
Los comandos que ejecutamos normalmente pueden recibir opciones y argumentos
(parámetros), como por ejemplo ls -l ./ . En ese ejemplo, ls es el comando, l es una opción y ./ es
un argumento. En esta sección veremos las variables especiales que nos permitirán luego hacer que
nuestros scripts se comporten del mismo modo, que puedan recoger opciones y argumentos.
#!/bin/bash
En primer lugar tenemos la barra invertida \ . Usaremos la barra invertida para escapar
caracteres especiales. Si queremos sacar por pantalla con el comando echo unas comillas o un signo
de dolar, la única forma es anteponiéndole una barra invertida, de otro modo sería interpretado como
comillas de fin de cadena de texto o como variable respectivamente.
Por último tenemos la variable especial $# . Esta variable contiene un número entero, que vale
el número de parámetros que pasamos al script sin contar $0. Ejecutemos el script de dos formas
distintas para comprender todo esto:
edison@edison:~/Programas> chmod +x [Link]
edison@edison:~/Programas> ./[Link]
$0 contiene ./[Link]
$1 contiene
$2 contiene
En total hay 0 parametros
edison@edison:~/Programas>
Estas dos ejecuciones han debido servir para ilustrar cómo funcionan estas variables especiales
para recibir parámetros en nuestros scripts. Conforme sigamos aprendiendo veremos cómo podemos
hacer que nuestro script se comporte de una forma u otra dependiendo de los parámetros que se le
pasen. Cada vez más, nuestros scripts se irán pareciendo a programas "de los buenos".
33
Administración de Sistemas Linux Comandos Básicos de Linux
Pasar y procesar argumentos
Muchas veces nos será necesario hacer que nuestro script se comporte de una forma u otra
según el usuario introduzca uno u otro argumento, o según una variable tenga tal o cual valor. En esta
sección pasamos a ver los comandos y estructuras que nos permiten hacer esto.
Lo que queremos evaluar recibe el nombre de EXPRESIÓN. test recibe las expresiones de un
modo un tanto especial. En el siguiente ejemplo comprobamos si dos números son iguales o no:
edison@edison:~/Programas> test 7 -eq 7
edison@edison:~/Programas> echo $?
0
edison@edison:~/Programas> test 7 -eq 8
edison@edison:~/Programas> echo $?
1
edison@edison:~/Programas>
En el siguiente comando estamos comprobando si 7 es igual a 8. Como era de esperar, el valor
de retorno de test es uno (1), lo cual indica que la expresión es falsa; 7 no es igual a 8.
Ahora supón que antes de todos aquellos comandos hacemos:
edison@edison:~/Programas> a=7
edison@edison:~/Programas> b=8
edison@edison:~/Programas> test $a -eq $a
edison@edison:~/Programas> echo $?
0
edison@edison:~/Programas>
y que repetimos todo lo anterior, pero en vez de usar 7 y 8, usamos las variables $a y $b. No hay
cambios, test reemplaza las variables por su valor y después efectúa la comprobación, siendo el
resultado final el mismo.
Existe además otra forma de llamar a test que no es con el comando, y que en nuestros scripts
puede ayudarnos a que con un sólo golpe de vista nos demos cuenta de qué es la expresión que se
evalua. Esta otra forma consiste en poner entre corchetes (y con espacio) la expresión a evaluar:
edison@edison:~/Programas> [ 3 -gt 2 ]
edison@edison:~/Programas> echo $?
0
edison@edison:~/Programas>
34
Administración de Sistemas Linux Comandos Básicos de Linux
Estructuras condicionales con IF: Hemos visto cómo evaluar condiciones con test. Con la ayuda de
las estructuras condicionales que crearemos con if y lo que ya hemos aprendido, podremos por fin
hacer que nuestros scripts se comporten de una forma u otra según las condiciones que nosotros
especifiquemos.
Las estructuras condicionales tienen este aspecto:
if EXPRESION1; then
# Bloque 1
elif EXPRESION2; then
# Bloque 2
else
# Bloque 3
fi
Este es el modelo más general con todas las opciones posibles. Si el valor de retorno de
EXPRESION1 es cero, las líneas de comandos de "Bloque 1" serán ejecutadas. El resto del bloque if
será ignorado en ese caso.
Si el valor de retorno de EXPRESION1 no es cero, pero el de EXPRESION2 sí que es cero,
entonces el "Bloque 1" no será ejecutado, mientras que el "Bloque 2" sí que será ejecutado. El "Bloque
3" será ignorado. Podemos poner tantos elif's como necesitemos.
Si ni EXPRESION1 ni EXPRESION2 ni cualquier otra de otros elif's que pongamos retornan
cero, entonces el "Bloque 3" será ejecutado.
Usamos fi para terminar la estructura condicional. Las EXPRESIONes son comandos con
test. Veamos un ejemplo sencillo:
#!/bin/bash
echo "Introduzca una numero: "
read input
if [ $input -lt 5 ]; then
echo "El numero era menor que 5"
elif [ $input -eq 5 ]; then
echo "El numero era 5"
elif [ $input -gt 5 ]; then
echo "El numero era mayor que 5"
else
echo "No introdujo un numero"
fi
En este sencillo ejemplo hacemos que el usuario introduzca un número que queda guardado en
la variable $input. Dependiendo de si el número es menor, igual o mayor que 5, el script se comporta de
una forma u otra (podemos añadir más líneas de comandos después de los echo's que aparecen ahí). Si
el usuario no introduce nada o introduce una cadena de texto, lo que hay tras else es lo que será
ejecutado, pues ninguna de las condiciones anteriores se cumple.
Las expresiones entre corchetes podrían haberse sustituidos estos corchetes por test.
35
Administración de Sistemas Linux Comandos Básicos de Linux
De todos modos, los elif y los else son opcionales, podemos crear una estructura
condicional sin ellos si no los necesitamos. Como muestra, el siguiente ejemplo:
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Necesito dos argumentos, el primero"
echo "es el fichero donde debo buscar y"
echo "el segundo es lo que quieres que"
echo "busque."
echo " "
echo "Uso: $0 <fichero> <patron_busqueda>"
echo " "
exit
fi
FICHERO=$1
BUSQUEDA=$2
if [ ! -e $FICHERO ]; then
echo "El fichero no existe"
exit
fi
NUM_VECES=`cat "$FICHERO" | grep --count "$BUSQUEDA"`
En primer lugar comprobamos que nos han pasado dos argumentos: el fichero donde buscar y la
cadena de búsqueda. Si no es así, le indicamos al usuario cómo debe ejecutar el script y salimos.
A continuación comprobamos que el fichero existe. Si no es así, advertimos convenientemente y
salimos.
Coloca estas líneas en un script y dale permisos de ejecución. A continuación, ejecútalo de las
distintas formas posibles: sin argumentos, con un fichero inexistente, con distintos patrones de
búsqueda, etc.
Dentro de un bloque de una estructura condicional puedes poner otra (ifs anidados), y dentro
de esa otra puedes poner otra y así sucesivamente. También podrás poner cuando las veamos, bucles y
otras estructuras, así como condicionales dentro de bucles, etc.
36
Administración de Sistemas Linux Comandos Básicos de Linux
Comprobar el valor de una variable con case: Escribiendo scripts, es muchas veces necesario
comprobar si el valor de una variable coincide con alguno de los que nosotros estábamos esperando, y
si así es, actuar de una forma u otra dependiendo de este valor.
Esto es posible hacerlo con if, y elseif, pero existe otra forma más eficiente y cómoda de
hacer esto: con la estructura case. Se usa como sigue:
#!/bin/bash
case $VARIABLE in
valor1)
#Bloque 1
valor2)
#Bloque 2
;;
.
.
.
.
*)
#Ultimo Bloque
;;
esac
valor1 y valor2 son valores que nosotros esperamos que la variable pueda contener, y Bloque 1 y
Bloque 2 son los bloques de comandos con lo que queremos que se haga en cada caso. Podemos poner
tantos valores reconocibles como queramos. Los puntos son precisamente para indicar aquello. El *
(asterisco) es un comodín exactamente igual que hacíamos moviéndonos entre directorios en capítulos
anteriores, cualquier cosa que no haya coincidido en alguna de las de arriba coincidirá aquí. Esto es
completamente opcional. No obstante, en el ejemplo siguiente te darás cuenta de su utilidad.
Los dos ";;" es necesario que se pongan al final de cada opción.
37
Administración de Sistemas Linux Comandos Básicos de Linux
#!/bin/bash
if [ $# -lt 1 ]; then
echo "Error. Esperaba al menos un parametro"
exit 1
fi
case $1 in
--opcion1)
echo "--opcion1 es una opcion reconocida"
exit 0
;;
--opcion2)
echo "--opcion2 es una opcion posible"
exit 0
;;
linux)
echo "\"linux\" es un argumento reconocido"
exit 0
;;
*)
En este ejemplo se hace que las opciones tengan que ir precedidas de un doble guión en forma
larga (la única que reconoceremos en este caso), de esta forma damos a nuestro script un aspecto y un
comportamiento más "profesional". Los argumentos no se suelen hacer preceder de ningún signo;
aunque todo esto puedes ponerlo como tú prefieras, lo importante es que aprecies cómo funciona este
tipo de estructura condicional.
Con exit salimos del script, haciendo que el valor devuelto sea 0 (éxito) o 1 (error) según los
parámetros fueran reconocidos o no.
Dentro de cada uno de los bloques de comandos se pueden poner estructuras condicionales con
if, o incluso otro case.
Pasar y procesar argumentos
Los bucles en bashscripting difieren un poco de lo que son en la mayoría de los lenguajes de
programación, pero vienen a cumplir una misión similar; a solucionar el problema de "Quiero que mi
script haga esto mientras se de esta condición", o "Para cada uno de los elementos siguientes, quiero
que mi script haga esto otro".
Así, tenemos dos tipos de bucles diferentes en bash: for y while.
38
Administración de Sistemas Linux Comandos Básicos de Linux
Bucles con for: De los propósitos explicados anteriormente a solucionar por los bucles, for viene a
solucionar el segundo. Veamos algunos ejemplos:
edison@edison:~/Programas> for i in pedro pepe juan jose; do
> echo " Hola $i"
> done
Hola pedro
Hola pepe
Hola juan
Hola jose
edison@edison:~/Programas>
En primer lugar apreciamos que todo lo que se puede hacer en un script también se puede hacer
en bash. La estructura de for es la siguiente:
nombre_var es el nombre de una variable (el que nosotros queramos, y sólo el nombre, no precedida
de $). LISTA es una lista de elementos, que se la podemos dar como en el ejemplo anterior, ahí en ese
comando, o podemos poner una variable que ya contenga una lista de elementos (en este caso sí que la
precederíamos de $, para que sea reemplazada por los elementos de la lista que contiene). Después
aprenderemos otras formas posibles de expresar esa lista.
LISTA puede ser una lista de archivos dada implícitamente. Más concretamente, podemos usar los
wildcards que ya conocemos para referirnos a varios archivos con un nombre parecido:
#!/bin/bash
DIR=$1
if [ -z $DIR ]; then
echo "El primer argumento debe ser un directorio"
exit 1
fi
if [ ! -d $DIR ]; then
echo "El directorio debe exister"
exit 1
fi
for i in $DIR/.*; do
echo "Encontre el elemento oculto $i"
done
echo "saliendo...
39
Administración de Sistemas Linux Comandos Básicos de Linux
El elemento LISTA del bucle for, puede ser un comando entrecomillado con comillas
laterales; un comando tal que su salida sea una lista de elementos. Así, sería lo mismo:
for i in *; do
que:
for i in `ls`; do
Como ya sabemos usar el bucle anterior, este lo entenderemos con algunos pocos ejemplos:
#!/bin/bash
j=0
while [ $j -lt 10 ]; do
echo "j vale $j"
j=$[$j+1]
done
#Aqui sigue el flujo de ejecucion normal del script
Este ejemplo es interesante. La condición para que el bucle se siga ejecutando es que j valga
menos de 10. Observa la forma mediante la cual en cada ciclo del bucle sumamos 1 a la variable j.
40
Administración de Sistemas Linux Comandos Básicos de Linux
#!/bin/bash
MINUM=8
while [ 1 ]; do
echo "Introduzca un numero: "
read USER_NUM
#Comandos inferiores.....
echo "El script ha salido del bucle. Terminando..."
exit
La condición es que el bucle se ejecute siempre (test 1 siempre retornará TRUE, y el bucle se
seguirá ejecutando). Pero, si el número introducido es el mismo que el valor de $MINUM , break
hará que se salga de el bucle y continúe ejecutando los comandos inferiores. Ten en cuenta que en bash
scripting, usando la notación $[ ] para hacer cálculos sólo podemos usar números enteros. Además,
dentro de un bucle while se puede utilizar cualquiera de los elementos ya conocidos, siempre que se
haga correctamente.
Funciones
Si bien las funciones en bash scripting difieren de lo que son en la mayoría de los lenguajes de
programación, sí comparten, en cambio, su razón de ser básica. Una función en un script es un conjunto
de líneas (comandos) a los que se les da un nombre especial y pueden ser ejecutados desde cualquier
punto del script mediante el uso de ese nombre especial.
No se considera una buena práctica repetir en distintos sitios las mismas líneas de código. Así,
se agrupan en una función, y LLAMANDO a la función por su nombre, esas líneas son ejecutadas
dondequiera que la llamemos.
Una función se DEFINE de la siguiente forma:
function nombre_de_la_funcion () {
41
Administración de Sistemas Linux Comandos Básicos de Linux
nombre_de_la_funcion lo elegimos nosotros, y le podemos dar el nombre que queramos, con las
mismas condiciones que el nombre de una variable (no espacios, no caracteres extraños, etc.). Entre las
dos llaves ({ y }) se introducen los comandos que se quiere que se ejecuten cuando la función sea
llamada.
Un ejemplo sencillo podría ser el siguiente:
#!/bin/bash
#[Link]
function uso() {
echo "Este script recibe dos argumentos."
echo "El primero debe ser --opc1 u --opc2 ,"
echo "y el segundo debe ser un fichero existente."
echo "--"
}
if [ $# -ne 2 ]; then
uso
exit 1
fi
case $1 in
--opc1)
if [ -e $2 ]; then
echo "El script termino con exito"
exit 0
else
uso
exit 1
fi
;;
--opc2)
if [ -e $2 ]; then
echo "El script termino con exito"
exit 0
else
uso
exit 1
fi
;;
*)
uso
exit 1
;;
esac
De no haber usado aquí las funciones, tendríamos que haber reescrito los echo que dicen cómo
se usa el script una y otra vez en cada sitio donde los hubiésemos necesitado. Mientras no se ejecute el
script con los argumentos adecuados, llamamos a la función uso que explica al usuario cómo se debe
llamar el script. Esta estrategia es muy frecuente y útil en scripts más complejos con muchas opciones.
42
Administración de Sistemas Linux Comandos Básicos de Linux
Podemos definir tantas funciones como necesitemos, cada una con un nombre distinto. Además,
al igual que los scripts desde la línea de comandos, las funciones pueden recibir parámetros, que se
procesan de la misma forma: $1 $2 y demás se corresponden con el primer y el segundo parámetro
pasado a la función respectivamente.
Al convertirse la función en un "comando posible" dentro del script, los parámetros se le pasan
igual que a cualquier otro comando:
#!/bin/bash
function lista_parametros () {
echo "Se ha llamado a lista_parametros, son $#"
echo "parametros. Mostrando los parametros:"
echo " "
b=7
numparms=$#
local j=1
lista_parametros a b c d dsfad d
echo $b
echo $j
La función lista_parametros en este ejemplo recibe varios parámetros del mismo modo
que cualquier otro comando dentro del script, y se procesan igual que ya conocemos para los scripts.
Aquí hacemos uso de shift dentro de la función. Lo que shift hace es que $1 valga $2, que $2
valga $3, etc. para así recortar la lista de argumentos una posición quitando el primero de ellos. ¿Qué
conseguimos? Pues es sencillo, listamos todos los parámetros posibles, puesto que imprimimos el
primero por pantalla, luego el primero vale el segundo, que se imprime por pantalla, luego el primero
vale el tercero, que se vuelve a sacar por pantalla, y así con tantos como tengamos. shift nos ofrece
unas avanzadas posibilidades para procesar argumentos. En este ejemplo lo hemos visto dentro de una
función, pero todo esto es también aplicable a un script en sí mismo, fuera de una función.
Para terminar con este ejemplo, nos fijamos en local j=..., esto significa que la variable
$j sólo existe dentro de la función, de hecho, cuando hacemos echo $j fuera de la función, no
obtenemos ningún valor. La variable $b, al no ser DECLARADA DE ÁMBITO LOCAL, sino
GLOBAL, existe dentro de la función y fuera de ella, como se puede apreciar ejecutando el script.
Cualquier otra variable con valor en el flujo principal del script existe dentro de las funciones que
definamos.
Hemos dicho que cada función se convierte en una especie de "comando posible" dentro del
script donde está definida. Como si de un comando se tratase, y al igual que hacíamos con exit 0 o
exit 1 en el flujo principal del script, podemos hacer que la llamada a una función genere un valor
43
Administración de Sistemas Linux Comandos Básicos de Linux
de retorno de éxito o bien de error. Lo conseguimos con el comando return. Se usa exactamente
igual que exit en el script, pero usaremos return dentro de las funciones.
Usar las funciones en nuestros scripts nos dá amplias posibilidades en el sentido de reducir el
tamaño de éstos, y que sean más fáciles de interpretar si pasado un tiempo debemos estudiarlos y
modificarlos. Además, otra ventaja de usar funciones para líneas que se repiten es que si no lo
hiciésemos y quisiéramos modificar el comportamiento de esas líneas, deberíamos hacerlo en todos y
cada uno de los sitios donde las hubiésemos puesto. Con las funciones, si modificamos las líneas de la
función, ya queda modificada en todos los sitios.
Conclusiones
Es importante que practiques a hacer tus propios scripts, aunque sean sencillos, para consolidar
todo lo aprendido. Sólo con la práctica llegarás a dominar el bash shell scripting.
Recuerda la utilidad de los scripts a la hora de automatizar tareas que tengan que hacerse
frecuentemente; es mejor hacer un script que teclear todos los comandos necesarios cada vez que lo
necesitemos.
Posteriormente estudiaremos cron, que es un demonio que ejecuta lo que queramos a una hora
determinada e incluso periódicamente. Nos será especialmente de ayuda crear scripts que, por ejemplo,
hagan copias de seguridad automáticamente, y dárselos a cron para que los ejecute.
Otros comandos que iremos descubriendo nos permitirán hacer scripts que desempeñen tareas
de lo más variado.
44
Administración de Sistemas Linux Comandos Básicos de Linux
45
Administración de Sistemas Linux Comandos Básicos de Linux
Otros Comando Útiles en Linux
La descripción que se hace aquí de los comandos abordados es bastante básica, pero siempre se
puede recurrir a su página man.
Comandos Relacionados con la Entrada/Salida
De estos comandos hemos conocido ya unos cuantos en secciones anteriores: echo, cat, more,
less y las redirecciones más comunes. Ahora veremos algunos más:
head y tail: head sirve para mostrar (o redirigir a otra parte) el principio de un fichero o de la
información proveniente de un pipe o tubería. tail tiene exactamente el mismo cometido, con la
diferencia de que este último, lo que muestra es el final. Ejemplos:
$ head mifichero (1)
$ head -n 30 mifichero | less (2)
$ tail mifichero (3)
$ tail -n 35 mifichero > final_de_mifichero (4)
2. La opción -n se usa para indicar a continuación el número de líneas que se deben mostrar desde
el principio del fichero (o como en este caso, enviar a less).
3. Cumple exactamente la misma función que head, a diferencia de que mostrará las 10 últimas lí
neas del fichero.
4. Escribirá las 35 últimas líneas de mifichero en el fichero final_de_mi_fichero.
Además de leer desde un fichero, estos dos comandos pueden leer desde stdin, así que
podemos "conectarlos" a pipes o tuberías. Supongamos que estamos instalando un programa desde un
paquete de código fuente, y que ejecutamos make. Imaginemos que por cualquier motivo, make
produjese una larguísima salida de errores, tantos que no pudiésemos ver cuál es el primero de ellos.
Pero nosotros necesitamos saber cuál fue el primer error emitido para poder solucionar el problema.
Así que podríamos hacer:
$ make 2>/dev/stdout 1>/dev/null | head -n 20
Atención a la primera parte del comando. Recordando que las redirecciones de este tipo se
procesan de derecha a izquierda (las de 1>... 2>...), lo que hacemos primero es despreciar la salida
normal, y posteriormente, enviar stderr (la salida con errores) a la salida estándar, que con el pipe se
convierte en la entrada estándar del comando head, que lee automáticamente de ella, obteniendo así
nuestro resultado. (Nota que si hubiéramos puesto las redirecciones cambiadas de sitio, no habríamos
obtenido salida alguna.).
Una opción realmente útil de tail es la opción -f. Con ella, tail escribirá el final del fichero en
stdout y además permanecerá activo. Si algo se añade al fichero desde otro sitio también lo mostrará.
46
Administración de Sistemas Linux Comandos Básicos de Linux
Por ejemplo, abre una terminal y escribe:
$ touch fichero
$ for i in a b c d e f; do echo $i >> fichero; done
$ tail -f fichero
a
b
c
d
e
f
Mantén esta terminal abierta y pásate a otra terminal. En esta otra escribe:
$ echo "hoooooola" >> fichero
A continuación se muestran otros comandos relacionados con la entrada salida. El uso que harás
de estos comandos será más bien esporádico, por lo que simplemente los citamos. En sus respectivas
páginas man encontrarás opciones específicas para ellos.
• wc (Word Count, contador de palabras). Muestra el número de palabras, bytes y caracteres que
contiene un fichero determinado.
• strings. Muestra por pantalla los caracteres "imprimibles" de los ficheros binarios.
• tac. Hace exactamente lo mismo que cat pero muestra las líneas en orden contrario (desde la
última hasta la primera).
• sort. Muestra el contenido de un fichero, pero mostrando sus líneas en orden alfabético.
• cut tiene como uso principal mostrar una columna de una salida determinada.
Comandos Relacionados con la memoria y el disco
df
(Disk Free) : nos informa del espacio disponible de las unidades de disco (locales o de red) que
tengamos montadas
# df
[Link] 1K-blocks Used Available Use% Montado en
/dev/hdd1 6040288 3247924 2485528 57% /
/dev/hda2 11719052 3526412 8192640 31% /home
none 128008 0 128008 0% /dev/shm
Una opción útil de la que dispone es -m, que mostrará el espacio en MegaBytes.
Free
( Gestion
de la memoria RAM en Linux): En primer lugar, entendamos cómo se gestiona la
memoria física del sistema en Linux. El kernel tiende a tomar, primeramente, la memoria que necesitan
los procesos que corre. Conforme el sistema está en marcha más tiempo, el kernel toma prácticamente
la totalidad de la memoria física existente, dejando sólamente unos cuantos MB de memoria
físicamente libres. Muchas veces esto lleva a los principiantes en Linux a confusión, llegando a creer
que la gestión de la memoria que hace Linux no es eficiente.
47
Administración de Sistemas Linux Comandos Básicos de Linux
¿Y para qué usa esa memoria restante Linux? Pues la usa como buffers, esto es, guarda datos
para un más rápido acceso al disco duro, datos de programas que se abrieron, por si se vuelven a abrir,
que se invierta mucho menos tiempo en ello, etc. En definitiva, aprovecha la memoria físicamente libre
para agilizar tareas básicas. Por otro lado esto es bastánte lógico... ¿para qué te sirve tener una gran
cantidad de memoria RAM física libre? ¿Y si la usamos para hacer que el sistema vaya más rápido?
Mucho mejor ;), ¿no te parece?
Si la carga de tareas (procesos) que el sistema tiene que soportar lo carga y estos procesos (o
programas ejecutándose) necesitan esta memoria que se está usando como buffers, Linux borra estos
buffers de la memoria y la asigna a las nuevas tareas que la necesiten.
En definitiva, ¿cómo podemos saber la memoria que tenemos libre y lo que ocupa cada cosa
(procesos por un lado y buffers por otro)? La respuesta la tenemos en el comando free (la salida por
defecto es en KBs).
# free
total used free shared buffers cached
Mem: 256016 251304 4712 0 12236 177516
-/+ buffers/cache: 61552 194464
Swap: 409648 2964 406684
En el equipo de este ejemplo, hay 256 MB de RAM física instalada. De ellos, solamente 4 MB
están libres (de lo que deducimos que la máquina lleva tiempo encendida y que se han escrito buffers en
parte de la RAM). En la línea -/+ buffers/cache tenemos en used la cantidad de memoria estimada
que los procesos del sistema están usando, y en free, la suma de la memoria usada para buffers y caché
más la físicamente libre. Así, los procesos sólo están necesitando 60 MB de RAM, y el resto de
memoria usada está simplemente agilizando el sistema.
Ahora nos fijamos en la última línea. Ahí tenemos el uso de la partición SWAP de intercambio
de datos. Esta es una buena medida para saber lo "cargado" que está nuestro sistema. En este caso hay
escritos menos de 3 MB en la memoria SWAP, lo que pone de manifiesto que la máquina anda holgada.
Más tarde, en el capítulo de procesos descubriremos otros datos que nos permitirán hacernos una idea
de la carga del sistema.
du (uso del espacio de disco)
: El comando du nos indica el espacio que ocupa un directorio del sistema
de ficheros y todo lo que tiene debajo de él.
Es tan fácil de usar como útil: du directorio/.
Con él podemos comprobar dónde se acumula la mayor cantidad de espacio en disco de nuestro
sistema.
mc
(midnight commander) : Este es un programa que ofrece una interfaz de usuario basada en texto
bastante cómoda, generalmente para hacer operaciones con ficheros (especialmente réplicas de un
directorio y todo lo que haya debajo de él o copias grandes de una gran parte del sistema de ficheros), o
tener una "vista de pájaro" del sistema de ficheros.
48
Administración de Sistemas Linux Comandos Básicos de Linux
Su uso es intiutivo (y todavía más sencillo si tenemos habilitados los servicios de ratón en la
consola), y por ello no merece mucha más explicación. Recuerda este comando porque nos será útil en
el futuro.
file: Este comando nos indicará qué tipo de datos contiene el fichero que le pasemos como primer argu
mento.
Comandos útiles varios
Algunos otros comandos útiles varios que no encajan en las categorías de arriba. Los que no
queden descritos en esta sección, es que vendrán explicados con detalle en alguna sección posterior.
gcc, el compilador de C:
Probablemente profundicemos un poco más en él próximamente, pero por si
quieres hacer alguna cosa en C y no sabes todavía cuál es el compilador en Linux, gcc es el GNU C
Compiler. Si no lo tienes, necesitarás instalarlo desde los discos de tu distribución. La mayoría de los
sistemas UNIX responderán al comando cc como C Compiler, y ejectuarán el compilador que haya ins
talado en el sistema, en este caso, gcc.
Para crear un ejecutable desde los ficheros de código C, basta con que hagamos:
$ gcc fichero1.c fichero2.c [...] -o miejecutable
uname: Indica nombre y versión del sistema operativo. Usado con la opción -a muestra toda la
información.
$ uname –a
Linux hostname 2.4.21 #1 SMP Thu Sep 4 [Link] CEST 2003 i686 unknown
which: Le pasamos como primer argumento un comando, y nos dirá, de los directorios que existen en
$PATH, en cuál de ellos está, por ejemplo:
$ which ls
/bin/ls
touch: touch cambia la fecha de creación o de modificación de un archivo. Si no existe, lo crea vacío.
Lo más conveniente es leer su página del manual: man touch
49
Administración de Sistemas Linux Comandos Básicos de Linux
$ w
[Link] up 50 min, 4 users, load average: 0.00, 0.02, 0.06
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
user1 :0 - 18:16 ?xdm? 0.00s ? -
user2 pts/0 :0.0 18:18 0.00s 0.09s 0.00s w
user2 pts/1 :0.0 18:31 4.00s 4.08s 4.06s vim [Link]
user pts/2 :0.0 18:33 32:03 6.90s 0.02s -bash
$ who
ricardo :0 Sep 5 18:16
user1 pts/0 Sep 5 18:18 (:0.0)
user2 pts/1 Sep 5 18:31 (:0.0)
user2 pts/2 Sep 5 18:33 (:0.0)
date: El comando date mostrará la hora del sistema, y además, nos permite cambiarla con la opción -s.
whoami: El comando whoami muestra nuestro nombre de usuario.
Buscar archivos: find y locate
En Linux tenemos dos opciones si queremos buscar archivos en nuestros discos. Diferen en que
son conceptos totalmente distintos que a su vez cumplen necesidades distintas. En primer lugar, find es
el comando que se usa para buscar normalmente en el sistema de ficheros, y lo examina cada vez que
queremos hacer una búsqueda.
El comando locate se complementa con el comando updatedb. Este último comando, cuando lo
ejecutamos (sin opciones ni argumentos), crea una especie de "base de datos" de todos los ficheros y
directorios del sistema. De este modo, cuando queremos buscar algo con locate, simplemente este
programa busca en esta base de datos, lo cual es mucho más rápido que buscar en el sistema de archivos
directamente. Obvimanete esto tiene un inconveniente; si no actualizamos esta base de datos con
updatedb, la información que nos dará locate no será cierta.
Uso de find: El uso más común de este comando es el siguiente:
find <directorio> -name <nombre>
50
Administración de Sistemas Linux Comandos Básicos de Linux
Nota que para poder usar los wildcards que conocemos, simplemente debes encerrar el criterio
entre comillas simples. Se puede buscar por criterios de muchísimos tipos, para más detalles, mira la
página man. Recuerda que puedes detener la búsqueda igual que detenemos cualquier otro comando
con Control+C, y redirigir la salida como también hemos aprendido; find puede ser muy útil en tus
scripts.
Cuando siendo usuarios normales busquemos ficheros fuera de nuestro directorio personal, se
nos mostrarán algunos mensajes de error porque habrá directorios a los que no tendremos permiso para
entrar a buscar (p.e. /root). Estos mensajes de error nos despistarán a la hora de interpretar la salida, así
que podemos enviar stderr a /dev/null (ya sabes, find ... 2>/dev/null).
Uso de locate: En primer lugar, ejecutaremos el comando updatedb para actualizar la base de datos. Es
una buena idea poner este comando en cron como veremos posteriormente para que se ejecute
automáticamente todos los días a una hora en la que el sistema no tenga mucha carga. Esto nos
permitirá agilizar nuestras búsquedas.
A continuación, el uso de locate no es nada del otro mundo. Además, es mucho menos flexible
que find (lo cual es perfectamente comprensible una vez que nos han explicado su forma de funcionar).
locate sólo sirve para buscar ficheros por nombre, y en todo el sistema de archivos. Ejemplos:
# locate so
[... muuucha salida ...]
# locate '*.so'
[... las librerías del sistema ...]
La similitud con find es que los criterios con wildcards deben ser entrecomillados con comillas
simples. Las diferencias son: no nos permite especificar directorio, busca en toda la ruta al fichero (no
sólo en el nombre del fichero), y además, si le pasamos un criterio sin wildcards, devolverá todos los
nombres de fichero cuya ruta completa contenta ese criterio (nótese en el primer comando de ejemplo),
a diferencia de find que sólo devolvería los ficheros con ese nombre exacto.
51
Administración de Sistemas Linux Comandos Básicos de Linux
Man y las paginas del manual
Ya venimos usando esta útil funcionalidad algún tiempo. Es muy útil disponer de
documentación en formato electrónico en el sistema, de esta forma no hay que memorizar las opciones
de un comando de memoria.
Puede ocurrir que existan dos páginas del manual que se llamen igual y que estén en secciones
distintas. man sólo mostrará la primera de ellas, así que si queremos una específica, deberíamos indicar
su sección ( man SECCION comando).
Algunas distribuciones de Linux no traen instaladas las páginas del manual en español por
defecto, pero pueden tener ese paquete en los discos de instalación o en Internet, llamado generalmente
manpages-es o nombres similares.
Apagar y reiniciar la maquina desde el Shell
El comando poweroff se encuentra en la mayoría de las distribuciones Linux y sirve para apagar
la máquina. Generalmente el comando halt produce el mismo efecto. reboot reinicia la máquina. En
algunas distribuciones, solo root tiene permiso para usar estos comandos por defecto, así que si se
quiere que usuarios no privilegiados puedan apagar o reiniciar el sistema, se debe recurir a sudo o hacer
SUID estos archivos.
Tambien puede utilizar el comando shutdown para apagar o reiniciar el sistema desde la linea
de comandos.
52
Administración de Sistemas Linux Comandos Básicos de Linux
Procesos Señales
Introducción y conceptos básicos sobre Procesos y señales
En un sistema Linux, que como ya sabemos es multitarea, se pueden estar ejecutando distintas
acciones a la par, y cada acción es un proceso. Explicaremos en este capítulo como manejar los
procesos y aprovechar las peculiaridades de Linux en lo referente a la capacidad multitarea, activando
procesos en primer y segundo plano, mostrando listas y árboles de procesos, suspendiéndolos y luego
volviéndolos a activar, matándolos, haciendo que sigan ejecutándose una vez se halla cerrado sesión o
cambiando la prioridad de las tareas.
Cuando ejecutamos un comando en el shell, sus instrucciones se copian en algún sitio de la
memoria RAM del sistema para ser ejecutadas. Cuando las instrucciones ya cumplieron su cometido, el
programa es borrado de la memoria del sistema, dejándola libre para que más programas se puedan
ejecutar a la vez. Cada uno de estos programas que pasan a la memoria del sistema y son ejecutados es
lo que conocemos con el nombre de PROCESO. El tiempo que este proceso estuvo en la memoria del
sistema ejecutándose, se conoce como TIEMPO DE EJECUCIÓN de un proceso.
Como todo en los sistemas UNIX, y por extensión en Linux, los procesos también tienen un
dueño. Ese dueño es el usuario que ejecuta el programa que da lugar al proceso. Esto viene a explicar
parte de la seguridad de Linux en cuanto a permisos. Como los archivos (y dispositivos como más
adelante veremos) tienen un usuario, un grupo y unos permisos determinados asignados, y también los
procesos, un proceso contará de cara al sistema de ficheros con los permisos que tenga el usuario que lo
creó. Resumidamente, un proceso, respecto al sistema de ficheros, podrá hacer tanto como el usuario al
que pertenece. Un programa ejecutado por un usuario no privilegiado nunca podrá leer en /root o
borrar o escribir cosas en /usr/bin. Un usuario normal no podrá tampoco modificar parámetros de
procesos que no le pertenezcan. root podrá ejercer cualquier acción sobre cualquier proceso.
Un proceso puede crear a su vez nuevos procesos. En la práctica, todos los procesos son hijos
del primer proceso ejecutado durante el arranque, el proceso "init". Así, un proceso hijo, a pesar de ser
uno nuevo, guarda una relación con el proceso que lo creó (proceso padre).
53
Administración de Sistemas Linux Comandos Básicos de Linux
Procesos
Básicamente un proceso tiene las siguiente propiedades:
• Un número identificador, (Process ID o PID), identificador de proceso. Es necesario para
referirnos a un proceso en concreto de los varios en ejecución.
• Un PPID (Identificador del proceso padre), es el número que indica qué proceso creó al proceso
en cuestión.
• Un estado; habrá momentos en los que un proceso seguirá existiendo en el sistema, pero no
estará haciendo nada realmente. Puede estar esperando a que una SEÑAL le sea enviada (sobre
lo que trataremos más tarde) para volverse activo, o a nosotros como usuarios nos puede
interesar detenerlo o pausarlo bajo determinadas circunstancias. Los estados más importanes
son dormido (S), y en ejecución (R).
• Un dueño, generalmente es el usuario que lo ejecutó, y como ya se dijo, el proceso hereda los
permisos del usuario de cara al sistema de ficheros. Si un ejecutable es SUID, al ejecutarse, el
proceso resultante adquiere los permisos del usuario dueño del archivo. Generalmente, un
usuario normal no puede ejercer control sobre procesos que no le pertenecen.
• Una prioridad que determina su importancia. Ya vimos que no todos los procesos eran igual de
importantes. Veremos cómo cambiar la prioridad de un proceso más adelante.
Podemos ver las tareas y sus subtareas en una estructura anidada mediante el comando pstree.
Al ejecutarlo, veremos algo como:
edison@edison:~> pstree
init-+-5*[agetty]
|-bdflush
|-cron
|-devfsd
|-eth0
|-gdm---gdm-+-X
| `-gdmgreeter
|-keventd
|-khubd
|-kreiserfsd
|-kscand
|-ksoftirqd_CPU0
|-kswapd
|-kupdated
|-login---bash---pstree
`-syslog-ng
Aunque esta información estructurada resulta interesante, existen dos programas muy conocidos
cada cual más avanzado que muestran información mucho mas detallada sobre los procesos, estos
son ps y top.
54
Administración de Sistemas Linux Comandos Básicos de Linux
ps muestra una lista de los procesos en ejecución. Prueba ps u , que muestra los procesos que
pertenecen al usuario actual. La combinación más habitual de opciones es ps aux , que muestra
información detallada de todos los procesos en ejecución. Algunos de los campos más importantes
mostrados por ps son:
USER usuario dueño del proceso.
• PID número identificador del proceso.
• %CPU porcentaje de uso del microprocesador por parte de este proceso.
• %MEM porcentaje de la memoria principal usada por el proceso.
• VSZ tamaño virtual del proceso (lo que ocuparía en la memoria principal si todo él estuviera
cargado, pero en la práctica en la memoria principal sólo se mantiene la parte que necesita
procesarse en el momento).
• RSS tamaño del proceso en la memoria principal del sistema (generalmente son KBytes,
cuando no lo sea, se indicará con una M detrás del tamaño).
• TTY número de terminal (consola) desde el que el proceso fue lanzado. Si no aparece,
probablemente se ejecutó durante el arranque del sistema.
• STAT estado del proceso.
• START cuándo fue iniciado el proceso.
• TIME el tiempo de CPU (procesador) que ha usado el proceso.
• COMMAND el comando que inició el proceso.
La página del manual de Linux sobre ps es especialmente útil. Informa sobre otras opciones y
propiedades de los procesos en detalle. Al fin y al cabo, lo que ps nos muestra es una "instantánea" de
los procesos del sistema en el momento que ejecutamos el comando, así que a priori no podremos ver la
evolución.
top es la versión interactiva de ps, y tiene algunas utilidades interesantes añadidas. Si lo
ejecutamos en una terminal y sin opciones, aparecerá arriba información del sistema: usuarios, hora,
información del tiempo de funcionamiento de la máquina, número de procesos, uso de CPU, uso de
memoria (nótese las consideraciones que hicimos previamente sobre la gestión de memoria en Linux),
y uso del swap. A continuación tenemos una lista de procesos similar a la que nos mostraba ps con la
diferencia de que esta se actualiza periódicamente, permitiéndonos ver la evolución del estado de los
procesos.
55
Administración de Sistemas Linux Comandos Básicos de Linux
edison@edison:~> top
top - [Link] up 38 min, 3 users, load average: 0.25, 0.34, 0.28
Tasks: 88 total, 1 running, 87 sleeping, 0 stopped, 0 zombie
Cpu(s): 5.4% us, 0.7% sy, 0.0% ni, 94.0% id, 0.0% wa, 0.0% hi, 0.0% si
Mem: 513296k total, 501996k used, 11300k free, 47348k buffers
Swap: 1052248k total, 0k used, 1052248k free, 259972k cached
Con top, tenemos dos posibilidades de especificar opciones, bien en línea de comandos en el
shell, o bien interactivamente (mientras está en ejecución y sin salir de él). La página del manual de top
es también muy buena, con descripciones detalladas de los campos y de las opciones, tanto de línea de
comandos como interactivas. Léela y prueba las distintas opciones.
Tareas en Bash, programas en primer y segundo plano
El control de tareas es una interesante característica que bash nos ofrece. Así, cada programa o
tubería que se ejecute tiene asignado un número de tarea por parte de bash (diferente al PID). Los
programas que podemos ejecutar desde una línea de comandos pueden estar en primer o segundo
plano, y de hecho pueden pasar de un estado a otro. Una consola concreta está bloqueada cuando un
proceso está en primer plano, mientras que si está en segundo plano la consola está libre y podemos
teclear comandos en ella.
Esto está más relacionado con la terminal en sí (bash en nuestro caso) que con el concepto de
proceso que hemos aprendido. Normalmente al ejecutar un comando no recuperamos el prompt hasta
que éste no termina. La necesidad que nos surge es poder usar esa terminal sin abrir otra nueva a la vez
que nuestro comando sigue haciendo lo que tenga que hacer.
En bash, ponemos una tarea en segundo plano añadiendo un & al final del comando. El
comando se ejecuta mientras la terminal queda libre.
edison@edison:~> sleep 10 &
[1] 7427
edison@edison:~>
[1]+ Done sleep 10
edison@edison:~>
El comando sleep simplemente espera el número de segundos del primer argumento. Al
ejecutarlo en segundo plano, bash imprime la línea [1] 7427 y nos devuelve al prompt, aunque el
comando se sigue ejecutando ahora en segundo plano. El número entre corchetes es el NÚMERO DE
TAREA (o, también llamado trabajo o job) que bash le asignó al pasarlo a segundo plano, y el número
que hay a continuación (7427) es el número de proceso que ha generado la ejecución del comando.
Cada vez que al presionar INTRO hay novedades en la gestión de tareas, bash nos informa de ello. En
este caso, ha terminado la tarea [1].
56
Administración de Sistemas Linux Comandos Básicos de Linux
Teniendo una tarea en segundo plano, arrojará su salida a la terminal actual a pesar de todo.
Podemos usar las redirecciones que ya conocemos para evitarlo.
Para recuperar una tarea en segundo plano a primer plano, podemos usar fg, seguido de %N ,
donde N es el número de tarea que queremos recuperar, por ejemplo fg %2 traería a primer plano la
segunda tarea.
edison@edison:~> sleep 10 &
[1] 7718
edison@edison:~> fg %1
sleep 10
edison@edison:~>
Con una tarea en primer plano, podemos usar Ctrl+Z y la detendremos. Ahora podemos elegir
entre continuar con esta tarea en primer plano, o mandarla a segundo plano. Para continuarla en primer
plano, teclearíamos fg %1. Para seguirla en segundo plano, usaremos bg %1, suponiendo que es la
tarea número 1.
Un comando ejecutándose en primer plano puede ser cancelado con Ctrl+C, lo que a su vez
hará desaparecer al proceso resultante de la tabla de procesos del kernel.
Señales
Las SEÑALES son la forma que tienen los procesos de comunicarse entre sí, y el kernel de
comunicarse con ellos. Existe un número determinado de señales que se pueden enviar a un proceso, y
cada una de ellas tiene sobre él una acción distinta: pausarlo, reanudarlo, cancelarlo...
Conceptualmente, debemos entender, que un proceso recibe una señal, y tiene predeterminada
una forma de actuar ante esa señal. Así, hay un conjunto de señales ante las cuales todos los procesos se
comportan igual, sin embargo, hay señales ante las que procesos distintos se comportarán de manera
distinta, e incluso habrá procesos que ignoren determinadas señales. Habrá otras que no podrán ignorar
(la de detenerse, por ejemplo) porque son comunes a todos los procesos.
Las señales se denotan por SIGNOMBRE, donde NOMBRE es el nombre que se le da a la señal.
Además, las señales más usadas tienen un número de señal asociado. Veamos las más comunes:
SIGHUP (num 1) Causa que un proceso "relea" sus archivos de configuración. Todos los programas no
implementan esta señal.
• SIGINT (num 2) Interrumpir (cancelar) un programa. Es la señal que se le envía a un proceso
cuando presionamos Ctrl+C en teclado con un proceso en primer plano.
• SIGKILL (num 9) "Matar" un proceso. Los programas no pueden decidir cómo responder a
esta señal, terminan inmediatamente cuando la reciben. Sólo debería ser usada en el caso de
necesitar terminar un proceso que ha dejado de responder y no funciona adecuadamente.
• SIGUSR1 (num 10) Señal de usuario. Cada programa puede decidir cómo responder a esta
señal.
• SIGSEGV (num 11) Señal de violación de segmento (segmentation fault). Esta señal le es
57
Administración de Sistemas Linux Comandos Básicos de Linux
enviada a un proceso cuando intenta acceder a memoria que "no es suya", que está fuera de la
zona de memoria que ese proceso puede usar. El proceso es detenido inmediatamente.
• SIGPIPE (num 13) Tubería no existente. Esta señal se envía a un proceso que estaba
escribiendo a una tubería o pipe cuando el destino de la tubería ya no existe.
• SIGTERM (num 15) Terminar. Se envía esta señal a un proceso cuando queremos que termine
normalmente, haciendo lo que necesite antes de terminar.
• SIGCHLD (num 17) Hijo terminó. Esta señal se envía a un proceso padre automáticamente cada
vez que un proceso hijo termina.
Se puede ver información más detallada sobre las señales con man signal.
El comando kill SEÑAL PID es el que se usa para enviar señales a los procesos. Podemos
indicar varios PIDs para que reciban esa señal en un solo comando separándolos con espacios al final.
Son equivalentes:
edison@edison:~> kill -SIGKILL 1283
edison@edison:~> kill -9 1283
Mirar en cada momento qué PID tiene el proceso originado por un comando puede ser
incómodo. Por eso existe el comando killall SEÑAL nombre_comando, donde "nombre_comando"
es el nombre del comando que dió lugar al proceso en cuestión.
La página del manual de kill es importante, conviene consultarla.
Prioridad de los Procesos. El comando nice
Lo más común es tener muchos procesos a la vez ejecutándose en nuestra máquina. Pero no
todos son igual de importantes. Por ejemplo, si estamos grabando un CD, este debería ser un proceso
más importante que el resto, porque si el disco duro no envía los datos a la velocidad suficiente a la
grabadora, perderemos nuestro disco grabable. Así que le diremos al kernel: "si el procesador no puede
con todo, lo último que debes retrasar es la grabación del CD". Podríamos notar que el resto de
aplicaciones van más lentas, pero eso nos garantizaría en una mayor medida que la grabación no va a
ser interrumpida. La forma de conseguir esto es, ejecutando desde el principio el comando interesado
mediante nice, o bien, conseguir su PID si ya se está ejecutando y usar renice para cambiar su
prioridad.
edison@edison:~> nice -n PRIORIDAD comando
edison@edison:~> nice PRIORIDAD PID_PROCESO
PRIORIDAD es un valor que va desde 20 a +20 (con el signo incluido). 20 es la prioridad más alta (al
contrario de lo que cabría pensar), y +20 la más baja. Sólo root puede establecer un proceso a una
prioridad negativa, los usuarios como máximo pueden poner un proceso en prioridad 0.
COMANDO es el comando que queremos ejecutar (sólo aplicable con nice), el mismo comando que
ejecutaríamos normalmente con todos sus parámetros y opciones.
PROCESO (sólo aplicable con renice) cambia la prioridad del proceso cuyo PID es PID_PROCESO al
nuevo valor indicado.
58
Administración de Sistemas Linux Comandos Básicos de Linux
Instalación de Software Adicional
Instalar software adicional en Linux es sencillo, sin embargo, dada la diversidad de
distribuciones y sistemas de empaquetado del software las utilidades que manejan dichos paquetes son
distintas.
Métodos de Instalación
A la hora de instalar software adicional a la distribución que instalemos nos podemos encontrar con
varios sistemas de paquetes. Existen, a grandes rasgos, cuatro sistemas de paquetes en todas las
distribuciones de Linux: RPM, DEB, TGZ y EBUILD. Los tres primeros son binarios, y el cuarto se
trata de metapaquetes
Los paquetes binarios contienen el software ya en código de máquina (a excepción de los Source
RPM y demás que serán tratados más tarde), y pondrán los programas y ficheros de configuración en el
sitio adecuado del árbol de directorios para que los otros paquetes puedan encontrarlos. Los sistemas de
paquetes binarios se apoyan en una "base de datos" que guarda qué paquetes están instalados y cuáles
no, la versión de estos, etc... Así, cuando instalamos un paquete binario, tal como un RPM o un DEB,
además de crearse los ficheros necesarios para que el software pueda funcionar, se añade a esta base de
datos una entrada diciendo que el paquete ha sido instalado y asimismo se guarda su número de
versión. Algo parecido (pero no igual) ocurre con los ebuilds de Gentoo.
Conforme trates con estos sistemas de paquetes te podrá ocurrir que los datos de la base de
datos de paquetes no coincidan con lo que realmente hay en la máquina. Esto puede ocurrir mediante el
borrado accidental de ficheros sin desinstalar adecuadamente un paquete, o conflictos de versiones...
En cualquier caso dispones de opciones que te permiten instalar o desinstalar paquetes incluso si la
información de la base de datos de paquetes no es del todo coherente. Además, existen comandos para
"reconstruir" o arreglar la base de datos de paquetes. Las páginas man de los programas que se
mencionan a continuación te aportarán toda la información que necesitas al respecto.
Escogiendo el método de instalación (Binario vrs Codigo Fuente)
Como se ha nombrado antes, hay que decidir qué método vamos a utilizar. En principio siempre
deberemos optar por los binarios de nuestra distribución a no ser que sepamos realmente lo que
hacemos.
59
Administración de Sistemas Linux Comandos Básicos de Linux
Compilar un programa desde las fuentes puede sernos útil en máquinas donde se necesite un
rendimiento extremo o en casos en que necesitemos aplicar parches al paquete.
Binarios: Para la instalacion o actualizacion a partir de paquetes rpm podemos ejecutar los co
mandos mostrados:
# rpm -ivh [Link] (1)
# rpm -Uvh [Link] (2)
1. Instala el paquete mutt1.4.1. Para que funcione tienes que tener el RPM en el mismo directorio
en el que se ejecuta el comando.
2. En caso de que mutt ya estuviera instalado en el sistema, lo mejor es correr este comando puesto
que se mantendrán algunos ficheros de configuración. Se trata del comando para actualizar soft
ware.
Para desinstalar un paquete se ejecuta:
# rpm –e mutt-1.4.1-1 (1)
# rpm –e --nodeps mutt-1.4.1-1 (2)
Fuentes: En caso de que vayamos a compilar un programa por nuestra cuenta lo mejor es que leamos
los ficheros de ayuda README e INSTALL del paquete. Para descomprimirlo haremos (suponiendo el ar
chivo de fuentes descargado en el directorio actual):
# tar xvzf [Link]
Si el paquete es un .tar.bz2 haremos:
# tar jxf [Link].bz2
Los pasos "genéricos" son:
# ./configure
# make
# make install
Pero como las cosas pueden cambiar entre unos paquetes y otros lo mejor que podemos hacer es
leernos los ficheros de documentación que acompañen a dicho programa.
Para desintalar un paqute a partir de sus fuentes la forma generica es:
# make uninstall
60
Administración de Sistemas Linux Comandos Básicos de Linux
Compresión y Empaquetado de Fichero y Directorios en Linux
Introduccion
Hasta ahora hemos visto como manejarnos con varios comandos, con editores de texto, con la
shell y con el sistema en general. Sin embargo, no se ha entrado en un tema bastante común en el
mundo de la informática: la compresión de datos. En Linux hay diversas herramientas para empaquetar
y comprimir archivos a continuación te muestro un resumen de las más comunes, de acuerdo a la
extensión que comúnmente se acostumbra ponerles.
tar
Empaquetar tar cvf [Link] /archivo/mayo/*
.[Link] o .tar.z o .tgz (tar con gzip)
Empaquetar y comprimir tar czvf [Link] /archivo/mayo/*
.gz
Comprimir gzip -q archivo (el archivo o archivos lo
comprime y lo renombra como "[Link]")
Descomprimir tar xvf [Link] xzvf [Link] -d
[Link] (el archivo o archivos lo descomprime y
lo deja como "archivo")
Ver el contenido (sin extraer)Nota: gzip solo comprime archivos, no directorios.
.bz2
Comprimir bzip2 archivo (el archivo o archivos lo comprime y
lo renombra como "archivo.bz2")
bunzip2 archivo
Descomprimir bzip2 -d archivo.bz2 (el archivo o archivos lo
descomprime y lo deja como "archivo")
bunzip2 archivo.bz2
Nota: bzip2 solo comprime archivos, no directorios.
61
Administración de Sistemas Linux Comandos Básicos de Linux
.tar.bz2 (tar con bzip2)
Comprimir tar -c archivos | bzip2 > [Link].bz2
.zip
Comprimir zip [Link] archivos
.lha
Comprimir lha -a [Link] archivos
.arj
Comprimir arj -a [Link] archivos
.zoo
Comprimir zoo -a [Link] archivos
.rar
Comprimir rar -a [Link] archivos
62