Shell

De GLASS

Tabla de contenidos

Objetivos

Después de leer este capítulo conocerá el funcionamiento de la bash y el de las principales utilidades para la administración del sistema. Será capaz de entender el funcionamiento de los scripts de inicialización y configuración de un sistema GNU/Linux. Podrá elaborar sus propios shell scripts y sabrá además administrar los usuarios del sistema.

Introducción

¿ Qué es la shell ? La shell o línea de comandos es la interface con el sistema que nos permite ejecutar programas y comandos. De echo, la propia shell no es más que otro programa, un interprete de linea de comandos que puede ser utilizado para ejecutar, suspender, detener o incluso escribir otros programas. La shell ejecuta los comandos o programas introducidos desde la entrada estándar (teclado) o desde un fichero, pero además la shell es en sí misma un lenguaje de programación que, como otros lenguajes de alto nivel, permite variables, estructuras de control de flujo y funciones. Existen diferentes shells como Bourne Shell (sh), Korn Shell (ksh), C-Shell (csh y tcsh), o GNU Bourne-Again SHell (bash). Esta última: bash, es la shell por defecto de los sistemas operativos GNU y es compatible con sh, incorporando además, características de ksh. Dado que bash es la shell por defecto que nos encontraremos en los sistemas GNU será en la que se centrará esta documentación. Para saber mas:

info bash
man bash

Primeros Comandos

Mediante la shell podremos ejecutar los programas o ficheros contenidos en /bin o en cualquier otro lugar del sistema de ficheros. Basta con escribir la ruta completa al programa en cuestión y pulsar <ENTER>, si bien, para ejecutar un programa en ocasiones basta con escribir sólo el nombre del programa, ya que bash buscará dicho programa automáticamente en todos los directorios que le indique la variable de entorno $PATH. Del mismo modo, buscando el programa en los directorios especificados en la variable $PATH, bash intentará completar el nombre del programa o comando que estamos introduciendo si así se lo indicamos pulsando la tecla <TAB>. Además de los programas o ficheros ejecutables, bash incorpora una serie de comandos internos (builtin commands) que están implementados en la propia shell. Bash dispone también de palabras reservadas, variables y funciones que permiten crear estructuras condicionales, bucles, redirecciones y tuberias para crear comandos más complejos e incluso programas. Dado que bash es compatible con Bourne Shell (sh) incorpora los comandos internos de esta (Bourne Shell Builtins) además de los suyos propios (Bash Builtins). A continuación se listan algunos de los los comandos internos y palabras reservadas.

Bourne Shell Builtin:

:	   eval	    hash      test
.	   exec	    pwd	      times
break	   exit	    readonly  trap
cd	   export   return    umask
continue  getopts  shift     unset

Bash Bultins:

alias	echo	logout	type
bind	enable	printf	typeset
builtin	help	read 	ulimit
command	let	shopt	unalias
declare	local	source

Shell Reserved Words:

!	done	for	them	}
[[	elif	function	time
]]	else	if 	until
case	esac	in	while
do	fi	select	{

Comandos básicos

A continuación se describen algunos comandos básicos de la bash así como algunas utilidades básicas en la administración diaria de sistemas GNU/Linux. Los comandos se muestran ordenados alfabéticamente para facilitar su consulta.

cat
La orden cat se utiliza para mostrar el contenido de un archivo de texto. Si el archivo no es de texto, cat tratará de mostrarlo por pantalla en forma de caracteres. Como algunos de estos caracteres corresponden al aviso de señal audible es posible que la salida produzca algún pitido. La forma habitual de la orden de cat es esta:
cat <archivo_o_ruta_a_archivo>
cd
La orden cd significa cambiar de directorio y nos permite desplazarnos a lo largo de la jerarquía de ficheros del sistema. Es uno de los comandos integrados en la shell y uno de los más utilizados.
Formas de utilización:
cd ..
Sube un nivel en el árbol de directorios.
cd -
Retorna al directorio de trabajo anterior.
cd ~
Nos sitúa en el directorio home del usuario actual.
Equivale a utilizar cd sin parámetros.
cd <ruta>
Nos sitúa en la ruta especificada. Si la ruta empieza con
(/) es relativa al directorio raíz. De lo contrario será
relativa al directorio actual en el que nos encontremos posicionados.
Ejemplos:
Si suponemos que estamos posicionados en /home/pepito/docs/
cd ..
Nos coloca en /home/pepito
cd docs
Nos vuelve a situar en /home/pepito/docs
cd ../../juan
Nos situará en /home/juan
cp
Copia un archivo de un sitio a otro. Esta orden crea un nuevo archivo igual al original pero con el nombre especificado. Si no se especifica uno nuevo crea el archivo con el mismo nombre que el archivo original, siempre que el destino no sea el mismo que el origen. Mediante el parámetro -r esta orden es capaz de copiar recursivamente el contenido de todo un directorio.
Ejemplos:
cp lista1 lista2
Crea una copia del fichero lista1 llamado lista2
cp -r /etc /root
Copia el contenido del directorio /etc al directorio /root
cp /root/text /etc/motd
Copia el archivo text a /etc/motd, si el archivo de destino existe lo sobreescribe.
Nota:Utilice esta orden con cuidado. Dado que la orden cp no comprueba la existencia de un archivo destino con el mismo nombre que el de origen, es posible sobreescribir un archivo con el contenido de otro, perdiendo de esta manera su contenido.
find

Esta orden recorre el árbol de directorios evaluando una expresión. Entre otras cosas se puede utilizar para buscar ficheros o directorios que cumplan con unos determinados requisitos, de manera que find buscará en el directorio que se le indique (y en los subdirectorios). A continuación se muestran unos ejemplos, algunos de los cuales hacen uso de algunas expresiones regulares y caracteres especiales como (. * \!) cuyo significado se explicará a medida que vayan apareciendo, y más ampliamente en el apartado [Programación de Shell Scipts en Bash - Expresiones Regulares].

find juan -name README -print

Esta orden recorrerá el arbol de directorios que cuelga del directorio juan, situado en el directorio actual y mostrará la ruta a la ubicación de los archivos o directorios README que encuentre.

Nota: El parámetro -print muestra el resultado de la búsqueda y es el parámetro que se utiliza por defecto siempre que no utilicemos los parámetros -exec, -ls, -print0 ó -ok. Es por esta razón que en los ejemplos siguientes no se incluye este parámetro.
find . -name *.txt

Esta orden se comporta de manera similar a la anterior, busca todos los archivos cuyo nombre concuerda con el patrón especificado por la expresión regular (*.txt cualquier cadena de texto terminada en .txt). En esta ocasión la búsqueda se realiza en el directorio actual (.) y en todos sus subdirectorios.

find /var/log \! -name “*.gz” 

Busca en /var/log y en todos sus directorios los archivos que NO (\!) están comprimidos (extensión .gz) .

find /var/log -newer /etc/apache/httpd.conf

Muestra los archivos de /var/log que han sido modificados con posterioridad a que se modificara el archivo de configuración del servidor web Apache httpd.conf.

find /var/log -neweram /etc/apache/httpd.conf
find /var/log -newerat '5 minute ago'
find /var/log -newerct 'last month'
find /var/log -newermt '1:00 GMT'

El primer ejemplo muestra los archivos de /var/log a los que se ha tenido acceso (neweram) posteriormente a la modificación (neweram) del archivo httpd.conf. El resto de ejemplos muestra los archivos del directorio /var/log que han sido accedidos (newerat), cambiados (newerct) o modificados (newermt) hace más de 5 minutos, el mes pasado y la 1:00 h respectivamente.

Nota: Ver la sección (-D data_spec) de la página del manual man cvs 1 para saber más acerca de como especificar las fechas.
grep

Busca en los archivos especificados (o en la entrada estándar, si no se especifican) el texto o patrón indicado.

grep “register_globals =” /etc/apache/php.ini

Busca la cadena de texo “register_globals =” en el archivo de configuración del modulo php del servidor web Apache y muestra la línea completa que la contiene por pantalla.

Mediante el uso de expresiones regulares es posible realizar búsquedas de patrones más versátiles. En el siguiente ejemplo utilizamos la expresión regular [0-9] que especifica el rango de números comprendidos del 0 al 9.

grep ttyv[0-9] /etc/ttys

En este caso grep devuelve aquellas líneas que contengan la cadena ttyv seguida de un número que puede ir de 0 a 9.

Algunas opciones interesantes del comando grep son -i, que permite no hacer disticiones entre mayusculas y minusculas o -v, que muestra todas aquellas lineas que no contiene la cadena pasada.

ls

Lista el contenido de un directorio: archivos y directorios. Veamos unos ejemplos:

ls	

Utilizada sin parámetros muestra el contenido del directorio actual.

ls /var/log

Mostrará el contenido del directorio /var/log.

ls -F	

El parámetro -F marca mediante caracteres algunos archivos especiales. Así muestra una barra invertida (\) detrás de los directorios, un asterisco detrás de los ficheros ejecutables, un ( @ ) en los enlaces simbólicos y un ( = ) si el fichero es un socket.

ls -G

Del mismo modo que el parámetro -F, éste parámetro resalta los archivos ejecutables, los directorios y los enlaces simbólicos, pero lo hace resaltándolos con diferentes colores.

ls -R

Muestra los archivos y directorios de un directorio de manera recursiva, es decir. Si el directorio actual tiene archivos y directorios se muestran estos, así como el contenido de todos los subdirectorios, que cuelguen de esa rama del árbol de directorios.

ls -a

Muestra los dotfiles, es decir, todos aquellos archivos que empiezan por ( . ). Estos ficheros son ocultos, ya que por defecto no son mostrados por la orden ls.

ls -l

Muestra la lista de archivos y directorios del directorio actual en formato largo.

ls -lh

La opción h se utiliza junto a la opción l y muestra el tamaño de los archivos en un formato más legible (human readable), es decir, un archivo que ocupara 2490313 Bytes se nos mostraría como 2M y uno que ocupara 52396 Bytes aparecería como 51K.

ls -lah

Las opciones anteriores se pueden combinar, este ejemplo mostrará el resultado en formato largo, los dotfiles y el tamaño en un formato comprensible (human readable).

mkdir

Esta orden permite crear un directorio nuevo si el usuario dispone de los permisos necesarios. Ejemplos:

mkdir docs

Crea un directorio llamado docs en el directorio de trabajo actual.

mkdir /home/juan/docs

Crea el directorio docs en el home del usuario juan..

Si ejecutamos la orden:

mkdir /home/juan/docs/linux/admin

Se producirá un error si no existen los directorios intermedios docs y linux, informándonos de que el directorio de destino /home/juan/linux/docs/linux, no existe. Para evitar este mensaje de error podemos utilizar el parámetro -p :

mkdir -p /home/juan/docs/linux/admin/

Esta orden crea el directorio admin y todos los subdirectorios intermedios necesarios. Es decir, dado que el directorio home, probablemente ya exista en el sistema, no se crea, pero se crean los directorios intermedios: docs y linux. Finalmente se crea dentro del subdirectorio linux el subdirectorio admin.

mv

Mueve un objeto o una lista de objetos de un sitio a otro. Si el segundo argumento es un directorio existente, la orden moverá los objetos de la lista a ese directorio. Si se indican dos archivos, la orden sobreescribe el segundo archivo con el contenido del primero, perdiéndose el contenido original del segundo archivo. Es un error utilizar más de dos argumentos con este comando si el último argumento no es un directorio. A diferencia de la orden cp, con mv el origen es borrado de su localización actual.

mv documento1 documento2

Se crea o sobreescribe, si ya existe, el fichero documento2 con el contenido del fichero documento1, el documento original documento1 es borrado. mv doc1 doc2 doc6 /home/juan/docs

Los archivos doc1, doc2 y doc6 son movidos al directorio docs. Esto implica que los ficheros doc1, doc2 y doc6 sean borrados del directorio actual. Move también es capaz de mover toda una rama del árbol de directorios a otro lugar. Por ejemplo, si disponemos de la siguiente rama en el directorio home.

rama1
|-- archivo11
|-- archivo12
|-- archivo13
|-- archivo14
`-- subrama2
    |-- archivo21
    |-- archivo22
    `-- archivo23

y ejecutamos la orden: mv rama1 rama2 , se creará el directorio rama2 con todos los archivos y directorios contenidos en el directorio rama1. Es muy importante recordar que con mv los archivos son copiados al lugar especificado y posteriormente el archivo o directorio original es borrado.

rm

Borra los ficheros especificados (si no son directorios). Si el fichero no tiene los permisos de escritura habilitados, se nos informará por la salida de error estándar para solicitar confirmación antes de proceder a borrarlo. Cuando borramos un link simbólico con rm, no se borra el archivo referenciado por el enlace, sólo el enlace a éste.

rm /home/juan/lista2.txt
rm *.core

El primer ejemplo elimina el archivo lista2.txt del directorio /home/juan. El segundo eliminará todos los archivos que cumplan la expresión regular (*.core ) del directorio actual.

rm -d /home/juan/docs
rm -r /home/juan/docs

La primera orden (-d) permite borrar directorios cuando estos están vacíos. La segunda orden (-r) borra recursivamente todos los ficheros, directorios y subdirectorios del directorio /home/juan/docs así como el propio directorio docs estén vacíos.

vi Este comando ejecuta el programa vi. Vi es un sencillo editor de textos presente en la mayoría de sistemas UNIX, por lo que es importante estar familiarizado con su utilización. Mediante vi es posible visualizar y editar los archivos de configuración de los diferentes programas que se presentan a lo largo de esta documentación. Para saber más acerca de la utilización de este programa véase la sección Edición de texto con Vi

Otros comandos y utilidades

A continuación se muestran otros comandos y programas que podemos utilizar desde la bash, útiles para la administración diaria de un sistema GNU/Linux. Los comandos se muestran ordenados alfabéticamente para facilitar su consulta.

&
Se coloca detrás de la orden que lanza una aplicación para que esta se ejecute en segundo plano.
adduser
Permite crear un nuevo usuario en el sistema. El programa adduser crea las entradas necesarias en /etc/passwd y /etc/groups, el directorio HOME para el nuevo usuario, los dotfiles necesarios y el mensaje de bienvenida, ver Usuarios, grupos y permisos.
alias
Comando interno de la bash que permite crear nombres alternativos para la ejecución de un programa. Por ejemplo, si deseamos que siempre que utilicemos el comando ls se muestren los archivos ocultos y en formato largo:
alias  ls=”ls -las”
apropos
Busca información relativa al parámetro pasado, en las páginas del manual. Equivalente a la orden man -k <parámetro>.
bg
Reinicia un trabajo suspendido, y lo ejecuta en segundo plano (bakground). Si no se especifica un identificador del trabajo, entonces el comando se aplica al trabajo actual.
Nota:Hay que tener sumo cuidado en no confundir el identificador de un proceso (PID) con el identificador de un tragajo. Los PID son asignados y mantenidos por el sistema, mientras que el identificador de un trabajo es asignado y mantenido por la shell actual. En el ejemplo siguiente, [1] es el identificador del trabajo, y 1150 el PID del proceso.
melmak@super8:~$ vi &
[1] 1150
melmak@super8:~$ jobs
[1]+  Stopped                 vi
cat
Visualiza el contenido de un fichero, ver Comandos Básicos.
cd
Permite colocarnos en otro punto del árbol de directorios, ver Comandos Básicos.
chgrp
Cambia el grupo al que pertenece un fichero o directorio.
chmod
Esta orden se utiliza para modificar los permisos de un fichero o directorio, ver Usuarios, Grupos y Permisos.
chown
Cambiar el propietario de un fichero o directorio, ver Usuarios, Grupos y Permisos .
cp
Copia ficheros, ver Comandos Básicos .
env
Muestra el nombre y el valor de las variables de entrono exportadas.
expr
Permite evaluar expresiones aritméticas de comparación de cadenas o lógicas. Utilizado en algunos scripts. Por ejemplo, expr 6 + 6 devuelve 12
fg
Comando interno de la bash que permite traer a primer plano una aplicación que esté corriendo en segundo plano.
file
Determina de que tipo es un fichero dado:
melmak@super8:~$  file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped 
fsck
Chequea y repare el sistema de archivos Linux.
grep
Busca el texto indicado en el objeto especificado Comandos Básicos.
gzip
Comprime o descomprime el fichero o la lista de ficheros especificados mediante el estándar de compresión GNU/UNIX . Por defecto, a los nombres de los archivos comprimidos con esta utilidad se les añade la extensión (.gz). Los archivos comprimidos con gzip pueden ser descomprimidos con las ordenes gzip -d, gunzip o zcat.
halt
Detiene el sistema de manera inmediata.
hostname
Muestra o establece el nombre de la maquina.
info
Permite acceder a las paginas de información de los programas que dispongan de ellas. Cuando esto sucede, usted acostumbrará a encontrar una información mucho mas detallada en éstas que en las paginas man del programa. El formato de las paginas info permite una navegación más eficiente e intuitiva que con el formato utilizado por las paginas man.
jobs
Muestra la lista de trabajos que se están ejecutando en background..
kill, killall
Permite finalizar la ejecución de un proceso o trabajo enviándole la señal terminate al identificador del proceso (PID) o al identificador del trabajo (%)
kill 1150 Finaliza el proceso 1150
kill %2 Finaliza el trabajo 2
Kill -9 1150 Trata por todos los medios de finalizar el proceso 1150
Kill -HUP 253 Finaliza el proceso 253 y lo vuelve ha lanzar con el mismo PID
killall httpd Permite especificar el nombre del proceso en lugar de su PID
less
Al igual que more, muestra el contenido de de un archivo, si bien con less es posible desplazarnos hacia atrás y hacia delante. El programa less permite utilizar algunas de las características del editor vi como por ejemplo la búsqueda de palabras en el archivo. Less está especialmente indicado para leer archivos muy extensos dado que no necesita leer por completo el archivo para mostrarlo por pantalla.
login
Se utiliza para acceder al sistema o para cambiar de un usuario a otro en cualquier momento.
logout
Finaliza la sesión del usuario actual.
ls
Muestra el contenido de un directorio, ver [ Primeros Comandos – Comandos Básicos ].
man
Permite consultar la ayuda en linea disponible para cada aplicación en las páginas del manual. Las páginas del manual describen detalladamente cómo se utiliza una determinada orden. Por defecto, cada aplicación instalada en el sistema introducirá su propia documentación de ayuda en las páginas del manual. Para consultar esta ayuda basta con ejecutar man seguido del comando del cual queremos obtener ayuda. Por ejemplo:
man ls
man gzip
md5sum, ckesum
Calculan el checksum del archivo especificado. El checksum es un número calculado matemáticamente a partir del contenido de un archivo. Se utiliza con frecuencia para comprobar la integridad de los archivos descargados de Internet antes de proceder a su utilización.
mkdir
Crea un directorio, ver [ Primeros Comandos - Comandos Básicos ].
more
Al igual que cat, muestra el contenido de un fichero por la pantalla. En cambio si el fichero ocupa mas de una pantalla, more se detiene y espera a que se pulse la barra espaciadora. Al contrario que con less, more no permite retroceder en el texto visualizado.
mv
Mueve un objeto al sitio especificado, ver [ Primeros Comandos - Comandos Básicos ].
passwd
Permite cambiar el pasword de un usuario, ver [ Usuarios, Grupos y Permisos ].
ps, pstree
Informa del estado de ejecución en el que se encuentran los procesos que se están ejecutando en el sistema. La variante pstree muestra los procesos hijos ordenados en ramas que cuelgan de sus respectivos procesos padre.
pwd
Muestra el PATH o ruta al directorio en el que estamos situados.
rm
Borra un archivo, ver [ Primeros Comandos - Comandos Básicos ].
rmdir
Borra un directorio si éste esta vacío. Si no lo esta, es posible recurrir a la orden rm junto con el parametro -r.
set
Muestra y permite modificar el valor de las variables de entorno.
shutdown
Permite detener o reiniciar el sistema de manera inmediata o retardada.
su
Permite a un usuario normal inicial una sesión con los mismos privilegios que el superusuario o usuario root.
tail
Muestra por defecto las 10 últimas líneas del final de un fichero por la salida estándar. Normalmente se utiliza junto a la opción -f para monitorizar los cambios producidos en los archivos de log del sistema, ver [ Redirección de Canales – Redirección de la Salida Estándar ]
tar
Utilidad para archivar. Permite empaquetar varios archivos y/o directorios bajo un único nombre de archivo con extensión (.tar). Posteriormente, el archivo resultante puede comprimirse con la utilidad gzip, pasando a tener un archivo con extensión (tar.gz) también conocido como tarball. Este formato es muy popular para distribuir el código fuente de la mayoría de aplicaciones GNU.
tar -zxvf nombre_tarball.tar.gz
tar -cvf mi_tarball.tar .

El primer comando descomprime (z) el archivo con gzip y luego extrae (x) los archivos contenidos en el archivo pasado como parámetro (f file) he informa en todo momento de las acciones que se van realizando (v verbose).

La segunda orden crea (c create) el archivo (f file) mi_tarball.tar he informa de lo que hace (v verbose)

touch
Actualiza la fecha de acceso a un fichero si éste existe previamente, sino existe crea un fichero de longitud cero con la fecha y hora de acceso actual.
bash$ ls -l maria
-rw-r--r--  1 melmak  1002  0 12 jun 16:12 maria
bash$ touch maria
bash$ ls -l maria
-rw-r--r--  1 melmak  1002  0 17 jun 19:15 maria
unzip
Muestra, comprueba o extrae archivos comprimidos mediante el estándar de compresión ZIP.
which
Muestra la ruta completa al comando pasado como parámetro. Es muy útil para encontrar la ubicación de comandos o utilidades instaladas en el sistema.
who
Visualiza los usuarios conectados en el sistema.
zip
Empaqueta y comprime archivos en el formato de compresión ZIP. Compatible con los archivos tipo MSDOS.

Redirección de canales

Por defecto, un programa envía su salida a la salida estándar (stdout), esto quiere decir que el resultado de la ejecución del programa es mostrado por pantalla. Cuando esto sucede, el resultado se está enviando en realidad a un descriptor de fichero, en este caso a /dev/stdout (pues en UNIX todo es un fichero). Para redirigir la salida estándard (1) de un programa hacia un sitio diferente utilizaremos el carácter (>). Véase un ejemplo.

ls -l /home/juan 
ls -l /home/juan 1> /dev/stdout

El primer comando funciona de la forma habitual, esto es, envía su resultado a la pantalla. El segundo comando también reenvía la salida de la ejecución de la orden ls a la pantalla. Ambas ordenes se comportan exactamente igual, la primera reenvía el resultado de la ejecución a la salida estándar de forma implícita, el segundo lo hace de forma explicita.

Existen tres descriptores de fichero estándar:

/dev/stdin Representado también por el número 0.
/dev/stdout Representado también por el número 1.
/dev/stderr Representado también por el número 2.

Redirección de la salida estándard (stdout)

En determinados casos nos puede interesar que el resultado de la ejecución de un programa o comando sea enviada a otro lugar, por ejemplo, a un fichero.

ls -l /home/juan 1> mis_archivos.txt

Si no especificamos un descriptor de fichero estándar (0,1 ó 2), por defecto será la salida estándar la que sea redireccionada. Así, lo normal es escribir el ejemplo anterior como se muestra a continuación:

ls -l /home/juan > mis_archivos.txt

Ahora hemos redirigido el resultado de la ejecución del comando ls (stdout) a un archivo, el resultado que debería haberse mostrado por pantalla ha sido reenviado al archivo mis_archivos.txt. Por lo tanto esta redirección crea un archivo nuevo llamado mis_archivos.txt que contiene el resultado de la ejecución del comando que le precede.

Podemos utilizar la redirección de la salida estándar para para monitorizar la ejecución de un programa. Para ello podemos escribir la siguiente orden:

tail -f /var/log/archivo_log_a_monitorizar > /dev/tty12 &

De esta forma, la salida del programa tail es enviada constantemente (-f) al terminal virtual 12 (ttyv12). El simbolo & indica que la aplicación tail se ha de ejecutar en segundo plano (background).

Redirección de la salida estándar de error (stderr)

Si ejecutamos la orden grep sin parámetros, la aplicación nos informará de que esa no es la forma correcta de ejecutar grep.

bash$ grep
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information. 	

Esta información no llega a la pantalla desde la salida estándar (stdout), sino que es enviada allí desde la salida estándar de error (stderr). Si redireccionamos la salida estándar de error hacia un fichero (ejemplo 1) o hacia el dispositivo NULL (ejemplo2), este mensaje ya no aparece por pantalla sino que es enviado a un archivo o eliminado respectivamente.

Ejemplo1: grep 2> mensaje_error_grep.txt
Ejemplo2: grep 2> /dev/null

Redirección de adición a un fichero

Si utilizamos el símbolo (>>) en lugar de (>) en la redirección, la salida del comando es añadida al final del archivo de destino. Si este archivo no ha sido creado se crea en este momento, al contrario que sucede con (>), si el archivo de destino existe, no es sobreescrito.

ls -l /home/juan/docs/manuales > todos_mis_documentos.txt
ls -l /home/juan/docs/howtos >> todos_mis_documentos.txt

El fichero todos_mis_documentos.txt contendrá la lista con todos los documentos contenidos en los directorios manuales y howtos.

Redirección simultánea de stderr y stdout a un fichero

Para redireccionar stderr y stdout simultáneamente, se utiliza (&>). Por ejemplo: si introducimos en la shell un comando que no existe, bash responde con un mensaje de error. Si redireccionamos stderr y stdout al dispositivo NULL, el comando no informa de errores.

bash$  este comando no existe
bash: este: command not found
bash$  este comando no existe &> /dev/null
bash$

Redirección entre descriptores

Si en lugar de redireccionar una salida estándar hacia un fichero es necesario hacerlo hacia otro descriptor de fichero estándar, se ha de sustituir el fichero de destino por el carácter & seguido del descriptor de fichero seleccionado. Ejemplos:

ls 1>&1 Escribe la salida stdout en el descriptor de fichero stderr
ls 2>&1 Escribe la salida stderr en el descriptor de fichero stdout

Este tipo de redirecciones se suele utilizar para programar tareas que el sistema ejecutará automaticamente (cron) sin la necesidad de mostrar los datos por pantalla, o bien cuando queremos redireccionar ambas salidas a un fichero.

Redirección de la entrada estándar (stdin).

Si ejecutamos la orden cat sin parámetros, esta lee los caracteres que introducimos desde la entrada estándar. La entrada estándar por defecto leerá los datos que se introducen desde el teclado, si bien esto se puede cambiar utilizando la redirección la entrada.. La redirección de entrada se indica así:

comando [N]< fichero

Dónde N puede ser uno de los descriptores de fichero que conocemos (0,1 ó 2). Por defecto N vale 0 (stdin). De esta forma, el contenido de fichero es leído por el descriptor de fichero indicado.

cat 0< hola.txt
Hola Mundo !

Equivale a:

cat < hola.txt
Hola Mundo !

En ambos casos, cat lee los datos del fichero hola.txt, en lugar de esperar a leerlos del teclado.

Una utilidad práctica de este tipo de redirección podría ser este:

bash$  cat ver_bases_de_datos.txt
show databases;
bash$  mysql -uroot -ppasswd_bd < ver_bases_de_datos.txt
Database
mysql
test
bash$ 

En este caso el fichero redirigido a stdin contiene un comando MySQL (show databases) que es ejecutado por MySQL, el cual muestra las bases de datos cargadas. Del mismo modo, es posible volcar el contenido de la base de datos juan_db al sistema gestor de bases de datos MySQL, si el fichero que redirigimos contiene las sentencias SQL adecuadas.

juan -pmi_password juan_db < backup_juan_db.sql

Otro aplicación muy utilizada de este tip de redirección es la que permite crear y añadir contenido mediante el comando cat.

cat > fichero.txt <<FIN
Todo lo que escribes pasa al archivo fichero.txt.
Cuando cat encuentre la cadena de fin cerrará en archivo.
FIN
cat fichero.txt
Todo lo que escribes pasa al archivo fichero.txt.
Cuando cat encuentre la cadena de fin cerrará en archivo.

Concatenación de ordenes (Tuberías)

Una tubería o pipeline consiste en una concatenación de comandos de shell separados por el símbolo "|". Cuando se encadenan dos o mas comandos de esta manera, la salida del primero de ellos pasa, a través de una tubería, al siguiente comando. Es decir, los comandos leen la salida del comando que les precede.

Ejemplos: Saber si el paquete wget esta instalado en el sistema (Salackware)

root@super8:~# ls /var/log/packages/ |grep wget
wget-1.8.2-i386-2

Saber si el paquete wget esta instalado en el sistema (RedHat,openSUSE,Mandriva...)

root@super8:~#rpm -qa |grep wget
wget-1.8.2-i386-2

En ambos casos, el resultado del primer comando es procesado por grep que lo filtra y muestra sólo las lineas que contengan el patrón especificado. De esta manera usted puede saber fácilmente si el paquete wget esta instalado en el sistema.

Este otro comando borrararia de manera sencilla el paquete wget de un sistema Slackware.

root@super8:~# removepkg `ls /var/log/packages/ |grep wget`

Edición de texto con vi

Las razones que nos llevan a aprender como funciona este editor de textos pueden ser varias, pero sin duda la más importante de todas ellas es la extensa implantación de VI en cualquier sistema UNIX que se precie. Podemos aprender a usar otros editores de texto más versátiles, e incluso más rápidos para trabajar, pero VI siempre estará allí y los otros puede que no, razón de peso por la que es necesario, como mínimo, defenderse en el uso de este "viejo conocido".

Trabajar con vi

Para ejecutar el editor basta con introducir el nombre del mismo:

bash # vi nombre_de_fichero

Si especificamos un nombre de fichero éste se abre para ser editado, de lo contrario iniciaremos la edición de un nuevo archivo.

En Vi existen dos modos de trabajo diferentes. Al iniciar la aplicación nos encontraremos en el modo comando. En este modo el editor se encuentra a la espera de que introduzcamos algún comando. Los comandos están representados por la pulsación de teclas u ordenes que generalmente empiezan por “:“. Con sólo pulsar la tecla correspondiente a un comando este se ejecuta. Así para empezar la edición de texto en un documento en blanco pulsaríamos la tecla <i> y acto seguido (sin pulsar <ENTER>) se pasaría al modo de inserción procediendo a introducir el texto deseado. Para salir de este modo y volver al modo de comandos pulsaremos la tecla <ESC>. A partir de ese momento las teclas que pulsemos serán interpretadas como comandos.

La siguiente ilustración trata de mostrar los modos de trabajo de una forma más gráfica:

Modos de trabajo en Vi
Modos de trabajo en Vi

Comandos básicos

La mayoría de ordenes o comandos de VI, son la primera letra del nombre del comando en inglés, de modo que para insertar texto desde la posición actual se oprime la <i> (insert), para añadirlo, se oprime la <a> (append). Para moverse hacia adelante al inicio de la siguiente palabra <w> (si ponemos cifras delante, nos moveremos n palabras hacia adelante, por ejemplo <4w> avanza cuatro palabras). Para regresar al inicio de la palabra <b>.

Las mayúsculas de cada comando tienen un comportamiento similar. La <I>, inserta a partir del inicio de una línea. La <A>, para añadir al final de la línea. Para moverse entre palabras reales <W> (tener en cuenta que las palabras que contengan caracteres del tipo guión o acentos, serán consideradas por VI como dos palabras juntas), y para hacerlo en sentido contrario, hacia atrás <B>.

En resumen:

<i> Inserta
<a> Añade
<w> Avanza una palabra
<b> Retrocede una palabra
<I> Inserta al inicio de una línea
<A> Añade al final de una línea
<W> Avanza una palabra real (no tiene en cuenta los símbolos ni los caracteres extendidos)
<B> Retrocede una palabra real Las teclas de movimiento son útiles en el caso de que el teclado no tenga teclas de desplazamiento, sus combinaciones son las siguientes:
<h> Izquierda
<l> Derecha
<j> Arriba
<k> Abajo

Para desplazarse rápido a través del texto se usa:

<p> Desplaza hasta el primer carácter de una línea
<$> esplaza hasta el ultimo carácter de una línea
<G> Anteponiéndole un número nos lleva hasta esa línea (2G nos llevaría a la segunda línea)
<5> Poniendo una cifra y presionando <ENTER> nos desplazamos ese número de líneas en adelante desde la posición actual
<d> Borrar. Si anteponemos una cifra, borra ese número de lineas en adelante desde la posición actual
<c> Cambiar. Si anteponemos una cifra, cambia ese número de lineas en adelante desde la posición actual. Podemos cambiar el texto desde donde estamos hasta la siguiente palabra combinando las teclas <cw>
<x> Borra el carácter que hay delante
<p> Pega el texto que se haya borrado o cortado
<u> Deshace el último cambio
<o> Abre una nueva línea y pasa al modo edición

Para buscar y reemplazar podemos usar:

/ Al aparecer el prompt escribir la cadena a buscar y presionar Enter (Por ejemplo: /usuario o /[Ee][Tt][Cc] para encontrar la palabra etc tanto en mayúsculas como en minúsculas)
? Lo mismo que el comando anterior pero busca hacia atrás
n Va hasta la siguiente entrada en modo de búsqueda
: Conmuta a modo escape
s Sustituir. La sintaxis es la siguiente; :linea_inicio,linea_final/s/patron_antiguo/patron_nuevo/g. Un ejemplo podria ser :1,100s/unix/UNIX/g. Con la g del final los cambios son globales, sino sólo cambiaría las primeras coincidencias de cada línea
:w Escribe el archivo en disco
:q Abandona el archivo (si además no queremos guardar cambios usaremos :q!)
:wq Escribe el archivo y vuelve a consola
:e Edita un nuevo fichero (:e nombre_fichero)

Se pueden generar de manera fácil abreviaturas con Vi del siguiente modo:

:abbr Crea una abreviatura, su sintaxis es; :abbr UEE Unidad Económica Europea. Ahora cada vez que escribamos UEE se cambiará por la frase entera de modo automático.
Crtl-V Esta combinación de teclas deshabilita momentaneámente las abreviaturas

Podemos también insertar la salida de los comandos de la bash:

:r La r seguida de el símbolo de admiración, insertará la salida de un comando en el texto, veamos cómo; :r!ls (pone el contenido del directorio actual en el documento).
:%!uniq Elimina todas las líneas duplicadas
:12,50!sort Ordena de las líneas 12 a la 50

Programación de Shell Scripts en Bash

Como ya se dijo en la introducción de este capítulo, la shell dispone de los elementos necesarios (variables, estructuras de control de flujo y funciones), para realizar programas que puedan ser ejecutados por la propia shell. A estos programas se los conoce como shell scripts o guiones de shell. Un guión o shell script no es más que un archivo de texto que contiene ordenes iguales a las vistas hasta el momento, en las que sólo hemos utilizado la bash como un simple interprete de línea de comandos. Un shell script puede además incluir variables, funciones y estructuras de control del flujo mediante las cuales, la bash va a poder interpretar y ejecutar cada uno de los comandos que contenga el archivo de texto así como los builtins que permiten crear estructuras de control de flujo. Pudiendo crear de esta forma, desde sencillos guiones hasta complejos shell scripts capaces de interactuar con el usuario.

Es muy importante para un administrador de sistemas tener conocimientos de programación de shell scripts, incluso aunque nunca tenga que verse en la necesidad de escribir uno. Cuando un sistema operativo UNIX o GNU/Linux arranca, se ponen a trabajar una serie de shell scripts de inicialización y restauración del sistema así como otros de puesta en marcha y configuración de servicios. Basta con echar un vistazo al directorio /etc/rc.d para ver la cantidad de shell scripts implicados en estos procesos. El administrador de sistemas ha de ser capaz de, como mínimo, entender estos y otros shell scripts y/o modificarlos convenientemente.

Crear y ejecutar shell scripts

En primer lugar es necesario editar, con vi u otro editor, el archivo de texto o shell script. El siguiente, es un sencillo scpit de ejemplo.

#!/bin/bash
# Script Hola Mundo !
echo Hola Mundo !

Para poder ejecutar el shell script del ejemplo, se puede ejecutar cualquiera de los siguientes comandos.

sh hola_mundo
bash hola_mundo

Esto hará que la bash (sh suele estar “linkado“ a la bash) interprete los comandos escritos en el archivo hola_mundo. Si lo que deseamos es ejecutar el script que acabamos de crear como si se tratara de cualquier otro programa, es necesario otorgar al archivo los permisos necesarios. Por ejemplo:

chmod 555 hola_mundo (permisos de lectura/ejecución a todo el mundo)
chmod a+rx hola_mundo (permisos de lectura/ejecución a todo el mundo)
chmod u+rx hola_mundo (permisos de lectura/ejecución para el dueño)

Ahora podremos ejecutar el script con tan solo ejecutar la orden:

./hola_mundo

Dado que "." equivale a la ruta actual, "./holamundo" equivale a dar la ruta completa al script. Si queremos invocar al script sin necesidad de pasar la ruta absoluta, ponemos mover este archivo a /usr/local/bin para que esté disponible para todos los usuarios. Dado que este directorio probablemente esté en el path del usuario, no será necesario lanzarlo con (./nombre_script) bastará con escribir su nombre en la línea de comandos y pulsar ENTER.

Caracteres especiales

Existen una serie de caracteres que tienen un significado especial para la bash, esto implica que se ha de tener cuidado de no utilizarlos fuera de la función para la que han sido reservados. Se ha de tener cuidado de no utilizar estos caracteres como parte de nombres de variables o en las cadenas. Para poder utilizar estos caracteres en una cadena sin que sean interpretados como caracteres especiales deberemos utilizar el carácter especial de escape (\).

La tabla que sigue a continuación trata de recoger algunos de estos caracteres especiales junto a su significado.

Carácteres especiales y su significado
Carácter Ámbito Explicación
# Carácter Especial Comentario. Las líneas que empiezan con # (salvo #!) son comentarios.
; Carácter Especial Separador de comados. permite incluir varios comandos en la misma linea.
;; Caracter Especial Terminador en la opción case, ver [Estructuras de control de flujo]
. Bash Builtin Cuando es ejecutado desde la linea de comandos simplemente ejecuta el script indicado. Utilizado en un shell scrip equivale a source <nombre_archivo>, al igual que la directiva #include de C, permite referenciar datos y variables presentes en otro shell script.
. Nombre de Archivo Los nombres de archivos cuyo primer caracter es un punto (.) son considerados ocultos y por defecto no serán mostrados por la orden ls. Cuando lo utilizamos en nombres de directorios, un único punto representa el directorio actual y dos puntos representa al directorio padre.
bash$ pwd
/home/juan
bash$ cd ..
bash$ pwd
/home
bash$ cd .
bash$ pwd
/home
. Expresión Regular Utilizado como parte de una expresión regular representa a cualquier carácter simple.
" Carácter Especial Permiten que la shell interprete una cadena con espacios como una única entrada. Las comillas dobles resuelven las variables que contenga la cadena encerrada. Si ejecutamos:
nombre=“Juan“
echo “Mi nombre es $nombre“

el resultado obtenido será:

Mi nombre es Juan
' Carácter Especial Con las comillas simples, se evita que las variables sean resueltas por la shell. El ejemplo visto para las comillas dobles daria el siguiente resultado:
nombre=“Juan“
echo 'Mi nombre es $nombre'

se obtiene:

Mi nombre es $nombre
` Carácter Especial Indica a la shell que ha de ejecutar la cadena delimitada entre comillas invertidas. Entre otras cosas, permite almacenar en una variable el valor obtenido tras la ejecución de un programa.
Nombre=`whoami`
echo “Mi nombre es $nombre“

se obtiene:

Mi nombre es Juan

Nota: El comando whoami retorna el login del usuario que ejecuta este comando.

\ Carácter Especial Carácter de escape. Cuando este carácter se antepone a un carácter especial, éste es interpretado literalmente, en lugar de interpretarse como un carácter especial.
! Comparación de Expresiones Permite invertir el significado del operador test, pudiendo cambiar por ejemplo el significado de “igual“ (=) a “no igual“ (!=).
! Linea de comandos Utilizado desde la linea de comandos permite ejecutar la última orden almacenada en el history que empezaba con los mismos caracteres.
bash# tar -zxvf /home/juan/docs/manual-linux.tar.gz .
...
bash# !ta

Anteponiendo el carácter (!) y ta, se ejecutará la última orden almacenada en el historial que empiece por ta. En este caso se repetiría la orden anterior.

tar -zxvf /home/juan/docs/manual-linux.tar.gz .
* Linea de comandos Desde la bash realiza una función de comodín. El * por si solo puede ser sustituido por cualquier directorio.

ls * (Muestra todos los archivos del directorio, menos los ocultos) ls *log (Muestra todos los archivos que terminen en log.)

* Expresión Regular Junto con un punto (.*) representa cualquier número de caracteres.
* Operador Aritmético En este contexto, el carácter * representa el símbolo de la multiplicación.
** Operador Aritmético Representa el operador exponencial
? Expresion Regular Representa un carácter de comodín que puede ser sustituido por cualquier carácter.
? Linez de Comandos Desde la bash realiza la función de comodín, actuando del mismo modo que una expresión regular.
$ Si se antepone al nombre de una variable, indica el valor que esta almacena.
$@,$* Contiene todos los parámetros posicionales en una sola cadena de texto.
$$ Almacena el ID del proceso que identifica al script en la cual aparece.
$# Indica el número de parámetros posicionales pasados al llamar al script. Estos parametros se puden recuperar mediante $n, donde n es el número de parámetro y n=0 el propio nombre del script.
bash # mi_script parametro1 parametro2 ... parametroN

$0: vale mi_script

$1: vale parametro1

$2: vale parametro2

$n: vale parametroN

$#: vale N

$? Muestra el valor exit status retornado por el último programa ejecutado. Un script que no retorne el estado explícitamente mediante la orden exit <status> mostrará el exit status del último comando ejecutado en el scriipt. Por convenio, las aplicaciones UNIX retornan 0 en caso de exito y un valor diferente de 0 en caso de error.
[..] Expresión Regular Crea un comodín que puede ser sustituido por un rango de valores:

[a-z] Rango de caracteres (mayúsculas o minúsculas) que van de la letra A a la Z.

[A-Z] Rango de caracteres (mayúsculas) que van de la A a la Z.

[0-9] Rango o intervalo de números que van del 0 al 9.

[..] Equivale a la orden test para la comparación de expresiones.
[[..]] Permite realizar una comparación extendida de expresiones (a partir de bash 2.0.2) que posibilita hacer comparaciones de una manera más parecida a como se hace en otros lenguajes de programación (adoptada de ksh88).
[[ $num1 -lt $num2 ]]

La bash ve la expresión anterior como un sólo elemento que retorna un código 0 si “éxito“ , ver [Operadores y Comparación de Expresiones]

{..} Permite redireccionar la salida del código contenido entre las dos llaves, tanto de entrada como de salida. Ver [Script Lectura Remota al final del capítulo]
((..)) Permite evaluar las expresiones aritméticas. Por ejemplo si escribimos, n=$(( 2 + 2) asignamos el valor 4 a la variable n. Esta construcción es un mecanismo que permite manipular las variables en bash al estilo de la programación en C. Así, (( num = 50 )) establece la variable a 50 y (( num++)) incrementa en 1 el valor de la variable num.
| Tubería (pipe). Pasa la salida de la ejecución de un programa a la entrada de otro. Permite encadenar comandos unos con otros. Ejemplo:
ls * | grep *.core | wc -l
ls /var/spool/packages | wc -l

Muestra el número de archivos “.core“ del directorio de trabajo actual y el número de paquetes instalados en el sistema respectivamente.

& Ejecuta un proceso en segundo plano. En el interior de un shell script es posible ejecutar comandos e incluso bucles en segndo plano. Ver [Script bckgnd-loop al final del capítulo]
~ Directorio home. Referencia al contenido de la variable $HOME

Variables

Como en cualquier otro lenguaje de programación en bash es posible utilizar variables. Los principales tipos de variables son las variables de entorno y las variables de usuario. Las primeras forman parte del entorno del sistema y no es necesario definirlas, se pueden utilizar en cualquier momento desde el shell script y algunas como PATH se pueden incluso modificar. Las variables de usuario son las que define el propio usuario desde el shell script.

En bash las variables de usuario se definen de la siguiente forma:

nombre_variable=valor_variable

El signo “=“ permite asignar un valor a la variable recién creada. Es importante no dejar espacios entre el nombre de la variable, el signo “=“ y el valor de la variable. Al contrario que en otros lenguajes de programación, la bash no distingue unas variables de otras, es decir no hay tipos de variables. En bash todas las variables son consideradas caracteres, excepto cuando el valor de esta son sólo dígitos, en estos casos la variable es tratada como un número entero.

Para referirnos al contenido almacenado en una variable es necesario anteponer el símbolo $ delante del nombre de la variable.

Variables incorporadas

Las variables incorporadas están disponibles para su utilización sin necesidad de definirlas previamente. Consulte [Tabla 4.1] para conocer la función de las principales variables incorporadas como: $#, $?, $0, $* o $@ .

Parámetros posicionales

Los parámetros posicionales están representados por las variables $1, $2, hasta $n cuando estos parámetros existen. Los parámetros posicionales permiten pasar variables al script desde la linea de comandos. Por ejemplo si creamos un script que sume dos números, éstos se le pueden pasar en el momento de llamar al script:

bash $ ./script_suma 234 654

Operadores y comparación de expresiones

En bash es posible realizar una comparación lógica de dos operadores (numéricos o cadenas) mediante la orden test expresión o bien mediante el uso de corchetes [ expresión ].

Mediante la orden test es posible realizar los siguientes tipos de comparaciones:

  • Comparación de cadenas.
  • Comparación numérica.
  • Comparación con operadores lógicos.
  • Comparación con operadores de archivos.


Comparación de cadenas

Bash realiza la comparación de cadenas rellenando de espacios en blanco la cadena más corta y realizando posteriormente la comparación de los valores ASCII de cada uno de sus caracteres. Es posible utilizar los siguientes operadores:

== ó = Para comparar si dos cadenas son iguales.
!= Para comparar si dos cadenas no son iguales.
> Comprueba si una cadena esta por delante de otra (alfabéticamente)
< Comprueba si una cadena esta por detras de otra (alfabéticamente)
-n Para evaluar si la longitud de la cadena es mayor que cero. Equivale a [cadena] ó test cadena.
-z Para evaluar si la longitud de la cadena es cero.

Ejemplo:

#!/bin/bash
# Compara las cadenas introducidas como parámetros
if [ $1 = $2 ]
then
 echo "Las cadenas introducidas son iguales"
else
 echo "Las cadenas introducidas NO son iguales"
fi
exit 0
Nota:No se deben confundir el símbolo “=“ de asignación (sin espacios entre la variable y el valor asignado), con el símbolo “=“ de comparación.

Comparación numérica

Para la comparación de valores numéricos es posible utilizar los siguientes operadores:

-gt Verdadero si un número es mayor (greater) que otro.
-lt Verdadero si un número es menor (less) que otro.
-eq Verdadero si los dos número son iguales ( equal ).
-ge Verdadero si un número es mayor (greater) o igual (equal) que otro.
-le Verdadero si un número es menor (less) o igual que otro.

Ejemplo:

#!/bin/bash
# Compara las cadenas introducidas como parámetros
if [ $1 -eq $2 ]
then
 echo "Los número son iguales"   # Si el resultado de la comparación es cierto
else
 echo "Los números NO son iguales"  # Si no lo es
fi
if [ $1 -ge $2 ]
then
 echo "El número $1 es mayor o igual que $2" # Si el primer número es mayor
else                                         # que el segundo
 echo "El número $1 es menor o igual que $2" # Si no lo es
fi
exit 0

Comparación con operadores lógicos

También están disponibles los siguientes operadores lógicos:

! Negación.
&& Operador lógico AND.
|| Operador lógico OR.

Comparación con operadores de archivos

A continuación se muestran algunos de los operadores disponibles para su utilización sobre ficheros:

-a, -e Si el archivo existe.
-d Para saber si el archivo es un directorio.
-r Para saber si el archivo tiene permisos de lectura.
-w Para saber si el archivo tiene permisos de escritura.
-x Permite saber si el archivo es ejecutable.
-nt Permite saber si un archivo es más nuevo que otro: FILE1 -nt FILE2
-ot Permite saber si un archivo es más antiguo que otro: FILE1 -ot FILE2
-O Permite saber si soy el propietario del archivo.
-G Permite saber si el archivo tiene el mismo ID de grupo que yo.

Operadores aritméticos

Bash no es capaz de trabajar directamente con números decimales. Si estos son necesarios para la realización de un shellscript, es posible recurrir a aplicaciones como bc.

= Asignación, permite asignar una valor a una variable.
+ Suma.
- Resta .
* Multiplicación.
/ División
** Exponente
% Módulo, resto de la división entera.
+= Incrementa una variable en un valor constante determinado.
-= Decrementa una variable en un valor constante determinado.
*= Multiplica una variable por una constante determinada.
/= Divide una variable por una constante determinada.

Expresiones regulares

Una expresión es una cadena de caracteres, que pueden tener o no un significado más allá de su significado literal. Las expresiones regulares combinan estos dos tipos de caracteres y permiten crear unos patrones que indican los requisitos que una cadena de texto ha de tener para coincidir con dicho patrón. El principal uso de las expresiones regulares es la búsqueda de textos y la manipulación de cadenas.

Bash por si misma no es capar de reconocer expresiones regulares, pese a que es capaz de utilizar algunos patrones como * o ? para completar nombres de ficheros. En un script, las expresiones regulares son reconocidas y utilizadas por aplicaciones y utilidades como sed o awk.

Estructuras para el control del flujo de ejecución

Las estructuras para el control del flujo permiten alterar la ejecución secuencial de las instrucciones presentes en el script, que por defecto, se ejecutan una por una. En ocasiones, nos interesa que una orden sea ejecutada un número de veces que a priori desconocemos. Otras veces, deberemos ejecutar una orden sólo si se cumple una determinada condición. Las estructuras de control del flujo de ejecución permiten hacer frente a este tipo de situaciones.

Sentencias de repetición: bucles. (for, while, until)

Las sentencias de repetición permiten crear bucles. Un bucle es un conjunto de acciones o comandos que son ejecutados hasta que la condición de finalización del bucle se cumple.

for

La sentencia for permite crear iteraciones. Se utiliza para repetir una serie de órdenes un número determinado de veces. Estructura :

for arg in [lista]
do
sentencias ...
done

Comportamiento: La variable arg toma un valor diferente de la lista de valores proporcionados en cada iteración,de manera que para cada valor que tome la variable arg se ejecutarán todas las sentencias que hay entre las etiquetas do y done.

Si se omite in [lista] los elementos de la lista serán los parámetros posicionales pasados en la ejecución del script. Las estructuras que se muestran a continuación son por lo tanto equivalentes.

for arg
do
sentencias ...
done

equivale a:

for arg in “$@“
do
sentencias ...
done

Los valores de la lista pueden indicarse de varias maneras ya sea de forma explicita o implícita. Veamos algunos ejemplos: Mediante una lista con los diferentes valores:

#!/bin/bash
# Busca archivos *.txt ,*.core, *.tgz y .log
for extens==ion in txt core tgz log
do
ls | grep $extension
done
exit 0

Mediante una variable que contiene la lista de valores:

#!/bin/bash
# Busca archivos *.txt ,*.core, *.tgz y .log
variable=“txt tgz core log“
for extension in $variable
do
ls | grep $extension
done
exit 0

Ejecutando un comando que retorna la lista de valores: `comando` o $(comando)

#!/bin/bash
# Borra los archivos .core del directorio actual
for archivo in `ls | grep .core`
do
rm  $archivo
done
exit 0	

Mediante comodines de la bash.

#!/bin/bash
# Borra los archivos .core del directorio actual
for archivo in *.core
do
rm  $archivo
done
exit 0	

Bucles for al estilo de C.

#!/bin/bash
for ((n=1; n<=10; n++))
do
echo $n
done
exit 0
Nota:Es importante remarcar que en este tipo de bucles(estilo C) si deseamos especificar el número de iteraciones mediante una variable, en lugar de especificarlo directamente, no deberemos anteponer el símbolo ($) delante del nombre de la variable, como cabria pensar. Esto es así debido a que estamos utilizando una construcción con doble paréntesis ((..)). Ver [ Caracteres Especiales ].

while

La sentencia while es otra sentencia de repetición que permite ejecutar una lista de ordenes mientras se siga cumpliendo la condición especificada.

Estructura:

while expresión
do
sentencias ...
done

Comportamiento: Esta construcción evalúa una condición (expresión) al principio del bucle, y ejecuta las sentencias que hay entre do y done mientras esa condición sea cierta. Esta construcción, a diferencia de los bucles for, se utiliza cuando no se conoce de antemano el número de iteraciones del bucle.

Ejemplo:

#!/bin/bash
# Bucle mediante while
contador=0
limite=10
while [ "$contador" -lt "$limite" ]
do
  echo "$contador"
  contador=`expr $contador + 1` # expr evalúa el valor de una expresión
                               # También es posible utilizar
                               # contador=$(($contador+1))
                               # ambas construcciones dan el mismo resultado
done
exit 0

until

La sentencia until, al contrario que la construcción while, repite una lista de ordenes hasta que la condición especificada es falsa. En otras palabras, until repite la lista de ordenes hasta que se cumpla la condición dada, no mientras se cumpla esta.

Estructura:

until expresión
do
sentencias ...
done

Comportamiento:

Esta construcción evalúa una condición (expresión) al principio del bucle, y ejecuta las sentencias que hay entre do y done mientras esa condición sea falsa. Mediante until es posible implementar cualquier bucle while, tan solo es necesario que la condición a cumplir sea completamente la opuesta a la utilizada en while.

Ejemplo:

# Bucle mediante until
contador=0
limite=10
until [ "$contador" -ge "$limite" ]
do
  echo "$contador"
  contador=`expr $contador + 1` # expr evalúa el valor de una expresión
                                # También es posible utilizar
                                # contador=$(($contador+1))
                                # ambas construcciones dan el mismo resultado
done
exit 0

Bucles anidados

Un bucle anidado no es más que un bucle que incluye dentro de la lista de secuencias a iterar, una estructura para la creación de otro bucle, es decir, un bucle dentro de otro. Bash permite la creación de bucles anidados.

Ejemplo:

#!/bin/bash
# Bucles anidados
for numero_iteracion in 1 2 3
do
  echo "Iteración número $numero_iteracion"
  for numero in 1 2 3 4 5
  do
    echo "$numero "
  done
done
exit 0

Control de los bucles (break y continue)

Los comando break y continue posibilitan el control de los bucles. Con break, se detiene la ejecución del bucle, se finaliza sin realizarse más iteraciones. Mediante continue, se detiene la ejecución de los comandos de la iteración en curso y se inicia la siguiente iteración del bucle si la hay.

Cuando utilizamos break o continue en su forma básica (sin parámetros) se finaliza el bucle actual. En el caso de que el bucle esté anidado o embebido dentro de otro bucle, break sólo afectará al bucle actual. Para que break o continue afecten a bucles de niveles superiores, es posible utilizar la forma break N ó continue N, dónde N hace referencia al nivel del bucle del cual se ha de salir.

Sentencias condicionales (if, case, select)

Las sentencias condicionales permiten ejecutar una acción (orden o comando de la bash) si se cumple una determinada condición. Esta condición puede darse como resultado de una comparación de expresiones (ver, [comparación de expresiones]) o bien como resultado de una interacción con el usuario.

if

La sentencia if es una sentencia condicional que permite evaluar/testear una condición y realizar, o no, una lista de acciones como resultado. Las sentencias if también pueden anidarse (elif), a continuación se muestra la estructura de la construcción if con sus posibles variantes.

Estructura:

if [expresión-cierta] 
then
  sentencias ...
elif [expresion-cierta]
then
  sentencias ...
else
  sentencias ...
fi

Comportamiento:

La sentencia if evalúa la expresión que se encuentra entre corchetes. Si el resultado de la misma es cierto, ejecuta las sentencias que se encuentran tras “then“, si la primera expresión se cumple, ya no se evalúa la expresión que aparece detrás de elif (abreviación de “else if“ ). Tanto elif como else son opcionales, esta última solo se ejecuta si no es cierta ninguna de las expresiones if o elif anteriores.

Ejemplo:

#!/bin/bash
if [ -z "$1" ]  # Si no se pasan parámetros
then            # se muestra este mensaje		
    echo "No se han pasado parámetros" 
elif [ "$1" = "contraseña" ] && [ "$2" = "danone" ]
then            # si se pasan, entonces si el primero
                # es la palabra contraseña y el segundo
                # la clave danone la autenticación es
                # correcta
    echo "Contraseña correcta" 
else            # si no se cumple ninguna de las condiciones
                # anteriores, se muestra este otro mensaje
    echo "Has de poner la palabra"
    echo "contraseña seguida de la"
    echo "clave correcta"
fi
exit 0

case

Esta sentencia es similar a la sentencia switch utilizada en C/C++. La construcción case permite ejecutar un bloque de código de entre varios en función de un valor o valores que coincidan con una variable especificada. Gracias a esta construcción, es posible implementar de manera sencilla construcciones con muchos if/then/else. Una de las principales aplicaciones de esta sentencia es la construcción de menus interactivos.

case patrón in
condición1)
  sentencias ...
  ;;
condición2)
  sentencias ...
  ;;
condiciónN)
  sentencias ...
  ;;
esac

Comportamiento:

La cadena o variable patrón es comparada con condición1, condición2, hasta condiciónN. Si patrón coincide con alguna de las condiciones se ejecutan las sentencias para esa condición. La marca ;; permite delimitar el final del bloque de código a ejecutar para esa condición.

Ejemplos El siguiente ejemplo permite seleccionar una de las opciones del menú mostrado por pantalla.

#!/bin/bash
clear # limpia la pantalla
echo "  Selecciona una un libro (1,2 ó 3)      "
echo "  ---------------------------------     "
echo "1- El Silencio de los Corderos "
echo "2- La Lista de Shindler        "
echo "3- El padrino                  "
echo
echo "O bien introduce el nombre del autor de uno de ellos"
echo
read libro  # lee la cadena introducida por el usuario
case "$libro" in
"1" | "Thomas Harris" | "thomas harris")
echo
echo "Titulo: El Silencio de los Corderos"
echo "Autor:  Thomas Harris"
;;
"2" | "Thomas keneally" | "thomas keneally")
echo "Titulo: La Lista de Shindler"
echo "Autor:  Thomas Keneally"
;;
"3" | "Mario Puzo" | "mario puzo")
echo "Titulo: El Padrino"
echo "Autor:  Mario Puzo"
;;
* )   # Cualquier otra cosa
echo "Opción o nombre incorrecto!"
;;
esac
exit 0

select

La sentencia select fue adoptada de la Kron Shell y permite realizar construcciones de menús sin necesidad de tener que recurrir a la combinación de mensajes echo y la orden read. La orden select, muestra una lista (in list) de opciones por pantalla y por defecto lee los valores entrados desde el prompt PS3.

Estructura:

select variable [in list]
do
  sentencias ...
break
done

Comportamiento:

Las opciones que aparecen en la lista [in list] suministrada son mostradas por pantalla junto a un número de selección. Posteriormente espera a que el usuario introduzca su elección y variable pasa a valer lo especificado en la lista. Posteriormente se ejecutan las sentencias que hay entre do y done. Si se omiten los valores de la lista [list], por defecto se utilizan los parámetros posicionales pasados al script, o bien los parámetros pasados a la función, cuando el select esté dentro de una.

Ejemplo:

#!/bin/bash
PS3='Elige tu equipo de futbol preferido: ' 
# PS3 establece la cadena del prompt
echo
select equipo in "Barça" "Madrid" "Real Sociedad" "Otro"
do
 echo
 echo "Tu equipo favorito es: $equipo."
 echo
 break
done
exit 0

Funciones

Las funciones están presentes en la mayoría de los lenguajes de programación, una función es una parte de un programa que realiza un determinado proceso y tiene la particularidad de poder ser reutilizada (llamada) tantas veces como deseemos desde un mismo programa. Las funciones permiten reutilizar código haciendo que los programas sean más inteligibles y permiten simplificar la resolución de problemas complejos dividiendo estos en partes más sencillas.

El formato para la definición de funciones en bash es el siguiente:

nombre_funcion () {	
  sentencias ...
}

El formato para llamar a una función en bash es el siguiente:

nombre_funcion parametro1 parametro2 ... parametroN

Los parámetros son opcionales y son analizados por la función del mismo modo que un script trata los parámetros posicionales pasados al script.

Ejemplo:

#!/bin/bash
suma () {
result=`expr $1 + $2`
echo $result
echo
}
echo "Ejemplo de reutilización de código"
echo "mediante funciones"
echo
echo -n "Suma 1: 2+2="
suma 2 2 	# Llama a la función suma con parámetros
echo -n "Suma 2: 8+4="
suma 8 4		# Llama a la función suma con parámetros
echo -n "Suma 3: 1000+3="
suma 1000 3
exit 0

Usuarios, grupos y permisos

Todo proceso ejecutado en un sistema Unix tiene un propietario. El propietario puede ser un nombre predeterminado por el sistema (como sys, bin o daemon), o bien una persona normal que accede al sistema y realiza tareas con él. Cuando un sistema es utilizado por varias personas lo más deseable sería que el sistema fuera capaz de diferenciarlas para, por ejemplo, mantener la privacidad de los datos de cada uno de ellos. Para ello, cada usuario en un sistema Linux dispone de su propio nombre de usuario (username) que será utilizado para acceder al sistema (log in). En Slackware disponemos de una serie de scripts para poder trabajar con cuentas de usuario:

adduser Para añadir usuarios
userdel Para borrar un usuario
chfn Para cambiar la información de usuario
chsh Para cambiar la shell por defecto del usuario
passwd Para cambiar el password
groupadd Para crear un grupo
groupdel Para borrar un grupo
groupmod Para modificar un grupo

Crear un usuario

Para crear un usuario en Slackware podemos utilizar el comando adduser o bien crear la cuenta a mano, lo cual en algunas ocasiones resulta ser lo más conveniente. A continuación se describen ambos procesos:

Crear una cuenta de usuario con adduser

Para crear una cuenta de usuario mediante el script adduser será necesario logearse como root en el sistema y responder a una serie de preguntas que éste nos va realizando. Finalizado el proceso, dispondremos de un nuevo usuario en el sistema. Las preguntas que nos realiza el script adduser disponen siempre de una respuesta predefinida que, por supuesto, podremos modificar a nuestra conveniencia. Veamos cuales son y que significan estas preguntas: Login name for new user []: pepito

Este es el nombre que el usuario utilizará para iniciar una sesión en el sistema. No es recomendable utilizar mayúsculas ya que puede acabar resultando engorroso para la administración diaria del sistema.

User ID ('UID') [ defaults to next available ]:

El UID es el identificador de usuario, mediante este identificador el sistema sabrá que es lo que puede o no hacer el usuario, ya que es este número el utilizado para identificarle en el sistema. Los UID en Slackware se asignan a partir del número 1000 y por defecto se asigna el primer UID disponible.

Initial group [ users ]:

Todos los usuario son colocados por defecto en el grupo users, si bien esto puede modificarse.

Additional groups (comma separated) []:

Permite añadir al usuario a otros grupos. Un usuario puede pertenecer a varios grupos al mismo tiempo. El hecho de pertenecer a un grupo determinado puede otorgar o no una serie de privilegios para el usuario, así es posible crear grupos cuyos usuarios puedan acceder y modificar el contenido de un determinado directorio del sistema o utilizar recursos hardware del mismo como lectores CD-ROM por ejemplo.

Home directory [ /home/pepito ]

Por defecto cada usuario dispone de un directorio $HOME que se encuentra situado en /home/nombre_usuario. En este directorio es donde el usuario almacenará sus archivos privados, así como los archivos de configuración de su entorno.

Shell [ /bin/bash ]

Es el momento de especificar el PATH a la shell por defecto para la cuenta de usuario que se está creando, en los sistemas Linux por defecto se utiliza bash (/bin/bash).

Expiry date (YYYY-MM-DD) []:

De no especificar una fecha, las cuentas no expiran. Por motivos de seguridad a usted le podría interesar crear cuentas de usuario con fecha de caducidad.

Una vez rellenadas estas preguntas aparece un mensaje que le informa de todos los datos que usted ha introducido para la nueva cuenta. Llegado a este punto es posible detener el proceso, en caso de detectarse algún dato erróneo, o bien proceder a crear la cuenta pulsando <ENTER>.

New account will be created as follows:
---------------------------------------
Login name.......:  pepito
UID..............:  [ Next available ]
Initial group....:  users
Additional groups:  [ None ]
Home directory...:  /home/pepito
Shell............:  /bin/bash
Expiry date......:  [ Never ]
This is it... if you want to bail out, hit Control-C.  Otherwise, press
ENTER to go ahead and make the account.

Ahora se le da la oportunidad de introducir una serie de información adicional para el usuario que acaba de crear, todos estos datos son opcionales y podrán ser modificados o añadidos más tarde mediante el comando chfn.

Changing the user information for pepito
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:

Finalmente, se le pedirá que introduzca un pasword, si no lo introduce o éste es demasiado corto, el script simplemente nos avisará de ello pero si insiste le permitirá crear un usuario sin pasword. Lo recomendable es utilizar un pasword sencillo y que sea más tarde el propio usuario el que lo modifique con el comando passwd.

Cambiar la informacion de un usuario (chsh, chfn)

Para cambiar las propiedades de un usuario se utilizan los script chfn (change finger) y chsh (change shell). Tal como indican sus nombres respectivos, el primero permite cambiar la información de usuario, el segundo en cambio permite seleccionar la shell que utilizará ese usuario cuando inicie una sesión en el sistema.

Eliminar un usuario del sistema (userdel)

Eliminar del sistema al usuario que acaba de crear es tan sencillo como ejecutar el script userdel de la siguiente forma: bash # userdel pepito

Esto eliminará al usuario pepito del sistema, es decir, eliminará las entradas que hacen referencia a este usuario de los archivos /etc/passwd y de /etc/group. El directorio HOME de ese usuario: /etc/pepito no será eliminado del sistema a no ser que borre al usuario del sistema añadiendo el parámetro -r

bash # userdel -r pepito

Desactivar temporalmetne a un usuario

Como administrador del sistema, es probable que en alguna ocasión le pueda interesar desactivar el acceso al sistema a un determinado usuario. Para conseguir esto lo más fácil es modificar su contraseña, de tal manera que esta pueda ser recuperada en el futuro. El comando passwd permite realizar estas dos acciones de manera sencilla, así:

bash # passwd -l pepido

Modifica la contraseña del usuario pepito de manera que pepito se ve imposibilitado para acceder al sistema. Del mismo modo es posible restaurar la contraseña original para el usuario pepito de la siguiente forma:

bash # passwd -u pepito

Ahora el usuario pepito puede volver a logearse normalmente en el sistema como si nada hubiera pasado. Esta forma de proceder es poco ortodoxa en el sentido de que el usuario simplemente observara que no puede acceder a su cuenta, sin saber que ha pasado. Para impedir que el usuario acceda a su cuenta sin borrar esta y notificándole que se le ha deshabilitado el acceso, lo mas sencillo es cambiar la shell por defecto del usuario, ya sea desde el archivo /etc/passwd o mediante el comando chsh, de manera que su nueva shell sea un archivo como este:

#!/usr/bin/tail +4
Esta cuenta ha sido cancelada temporalmente
debido a un uso incorrecto de la misma.
Pongase en contacto con el administrador
del sistema y vaya buscándose un buen abogado.

Crear una cuenta de usuario manualmente

Para crear una cuenta de usuario manualmente se han de seguir los siguientes pasos:

  • Añadir una entrada en /etc/passwd editándolo con vipw, fijar el campo de la contraseña a x.
  • Si es necesario crear un nuevo grupo editar /etc/group con vigr.
  • Crear el directorio $HOME de usuario con mkdir en la ubicación especificada en /etc/passwd y establecer al usuario que estamos *creando como propietario del mismo:
  • Cambiar al propietario de archivo $HOME recién creado por el del nuevo usuario
  • chown -R pepito:users /home/pepito
  • Establecer una contraseña con passwd para el nuevo usuario.

Permisos

Un aspecto muy importante en cuanto a la seguridad de los sistemas multiusuario, es la posibilidad de poder establecer permisos sobre los archivos del sistema, de manera que sea posible permitir el acceso únicamente a aquellos ficheros que un usuario necesite. Como con los procesos, vuelve ha aparecer otra vez el concepto de propietario, en esta ocasión de un determinado fichero.

En los sistemas Unix es posible establecer permisos de lectura, escritura y ejecución diferentes para el propietario del fichero, el grupo al que pertenece el fichero así como para el resto de usuarios del sistema.

Un análisis detallado del resultado de la ejecución del comando ls permite entender cómo funciona el sistema de permisos en un sistema Linux.

bash $ ls -l /bin/bash
-rwxr-xr-x  1 root  wheel  819980 22 mar 17:44 /bin/bash

Este comando muestra información acerca del archivo /bin/bash. Lo primero que aparece empezando por la izquierda son: los los permisos del fichero (file mode), el número de enlaces, el nombre del propietario, el nombre del grupo al que pertenece, el tamaño en bytes, la fecha abreviada de la última modificación, la hora y el minuto de dicha modificación y finalmente la ruta al archivo.

Permisos (File Mode)

El significado de los permisos del fichero son los siguientes:

El primer carácter se utiliza para marcar algunos ficheros especiales. En el caso de los directorios vale d. Los tres caracteres siguientes establecen los permisos que tiene el propietario sobre este archivo, la tripleta siguiente indican los permisos establecidos para el grupo, finalmente la última tripleta indica los permisos establecidos para el resto de usuarios.

Los valores rwx indican permiso de lectura (read), escritura (write) y ejecución (execute) respectivamente. Si en el lugar de aparecer estas letras aparece en un guión “-“ significa que no se dispone de ese permiso para el usuario al que afecte, es decir en función de si es la tripleta de permisos del propietario, del grupo o del resto de usuario.

Carácteres especiales y su significado
File Type Propietario Grupo Otros
b r w x r w x r w x
c s s t
d S S T
l
p
-
File Types
b Block special file.
c Character special file.
d Directory.
l Symbolic link.
s Socket link.
p FIFO.
- Regular file.
File Mode
r Se puede leer
w Se puede escribir
x Ejecutable
s set-user-ID habilitado
S set-user-ID y permiso de ejecución habilidados
t sticky-bit
T sticky-bit y permiso de ejecución habilitados

set-user-ID

El atributo set-user-ID hay que utilizarlo con mucha precaución, ya que permite que un usuario o grupo acceda al fichero como si fuera el propietario de mismo o como si perteneciera al grupo al que pertenece el fichero afectado. Para evitar fallos de seguridad, la mayoria de sistemas GNU/Linux ignoran este atributo cuando se trata de scripts. De esta manera evitaremos que un usuario sin privilegios pueda ejecutar comandos como el usuario root por ejemplo.

El comando sudo sule tener este atributo activado.

super8:~ # ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 120696 Nov 25 18:40 /usr/bin/sudo

sticky-bit

En muchas distribuciones, el sticky-bit suele activarse en algunos directorios en los que todo el mundo puede escribir. El directorio /tmp suele tener permisos de escritura para todo el mundo. Esto implica que cualquier usuario puede borrar ficheros creados por otros usuarios en este directorio. Para evitarlo, muchas distribuciones añaden el atributo sticky-bit a este directorio. De esta manera, pese a que todos podran escribir en dicho directorio, solo el dueño del fichero podrá eliminarlo.

super8:~ # ls -ld /tmp/
drwxrwxrwt 87 root root 20512 Dec 28 16:45 /tmp/

Cambiar los permisos de un fichero

Mediante el comando chmod (change mode) es posible modificar los permisos de los ficheros. Su estructura es esta:

chmod modo nombre_archivo

Donde modo puede especificarse en formato numérico o mediante letras.

El formato numérico consiste en especificar mediante tres números en octal los valores que representen los permisos que deseamos establecer.

letras aparece en un guión “-“ significa que no se dispone de ese permiso para el usuario al que afecte, es decir en función de si es la tripleta de permisos del propietario, del grupo o del resto de usuario.

File Modes
Lectura Escritura Ejecución Valores
- - - 0 + 0 + 0 = 0
- - x 0 + 0 + 1 = 1
- w - 0 + 2 + 0 = 2
- w x 0 + 2 + 1 = 3
r - - 4 + 0 + 0 = 4
r - x 4 + 0 + 1 = 5
r w - 4 + 2 + 0 = 6
r w x 4 + 2 + 1 = 7
Aplicando este pequeño ejercicio mental para generar los números pertenecientes a los permisos del propietario, grupo y el resto de usuarios, se obtiene una tripleta de tres números que especifican el file mode del fichero. Ejemplos: Para otorgar permisos de lectura, escritura y ejecución para el propietario y de lectura y ejecución para el grupo y el resto de usuarios se utiliza el comando: chmod 755 nombre_fichero Si se ha entendido nada de lo explicado, o símplemente le parece engorroso, existe un método más “humano“ para especificar los permisos de un fichero. Este método utiliza también el comando chmod pero especifica los permisos mediante letras. Ejemplos: chmod u+x nombre_archivo chmod u-x nombre_archivo chmod a+r nombre_archivo chmod ug+s nombre_archivo Ahora el modo se especifica mediante una combinación de letras. Las letras que aparecen antes de los símbolos “+“ y “-“ indican a quien afectan los permisos que se indican tras los símbolos “+“ y “-“. Las letras que se pueden utilizar para especificar a quien afectan los permisos son “u“ para el propietario, “g“ para el grupo, “o“ para el resto de usuarios y “a“ para todos. Las letras que se pueden utilizar para especificar los permisos aparecen el la tabla anterior.
Imagen:32px-agt_update_critical.pngNota: El que un directorio tenga el permiso de ejecución habilitado equivale a decir que es posible ver el contenido del mismo. Por otro lado los permisos del directorio afectan y a todos los ficheros y subdirectorios que este contenga, prevaleciendo sobre estos.

Cambiar al propietario de un fichero

Además de cambiar los permisos del fichero, se hace necesario el poder cambiar al propietario de un fichero, para realizar esta labor se utiliza el comando chown (change owner).

chown nuevo_propietario:nuevo_grupo nombre_archivo

Ejemplo:

chown pepeito:users /home/pepito

Este comando establecería al usuario pepito como el propietario del directorio /home/pepito y al grupo users como el grupo del directorio.

su y sudo

Un sistema Linux tiene como mínimo una cuenta, la cuenta de root o superusuario. Dado que este usuario tiene permiso para hacer de todo, es una cuenta que hay que utilizar con suma precaución, pues de lo contrario tarde o temprano haremos algo indebido y de consecuencias graves e incluso irreparables. Para no correr el riesgo de dañar el sistema es muy recomendable crear un usuario “normal“ y trabajar con él para la administración diaria del sistema. Sin embargo, en ocasiones, usted se verá en la obligación de realizar acciones que sólo el usuario root esta capacitado a realizar. ¿ Deberá usted cerrar la sesión actual y volver a “logearse“ como usuario root cada vez que esto suceda ? Evidententemente la respuesta es no, ya que existen un par de utilidades que le facilitaran la vida.

La primera de ellas es la orden su, mediante ella usted puede convertirse en el usuario que desee sin tener que abandonar la sesión actual. Por defecto, cuando se utiliza sin parámetros, su le permite convertirse en superusuario.

melmak@super8:~$ id 
uid=1000(melmak) gid=100(users) groups=100(users),0(root),10(wheel)
melmak@super8:~$ su
Password:
root@super8:/home/melmak# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)
root@super8:/home/melmak# exit
exit
melmak@super8:~$ id
uid=1000(melmak) gid=100(users)
groups=100(users),0(root),10(wheel)
melmak@super8:~$

Tal como se aprecia en el ejemplo, su solicita la contraseña del usuario en el que uno se pretende convertir, lo que obliga a conocer la contraseña del mismo, el superusuario, en este caso.

La orden su le facilita la operación de convertirse en otro usuario distinto pero le obliga a conocer la contraseña del usuario en el cual se desea convertir. Para solucionar estos dos inconvenientes se puede recurrir a la utilidad sudo. Sudo le permite ejecutar un comando como si fuera otro usuario, de esta manera le evita tener que “logearse“. Por otro lado sudo no requiere que usted conozca la contraseña de otros usuarios, sólo la suya. Si usted esta autorizado a utilizar sudo, mediante el archivo /etc/sudoers, podrá ejecutar las ordenes que en este archivo se especifiquen. Por defecto, sudo le solicitara la contraseña la primera vez que se utilice, en posteriores llamadas ya no se la pedirá, a no ser que exceda un tiempo prefijado, además es posible configurar sudo para que no solicite contraseña.

Para editar el archivo de configuración de sudo usted debe utilizar el comando visudo.

Herramientas personales