Cerramos del 10/08 al 18/08. Los pedidos cursados a partir del 09/08 a las 12.00 hora de España peninsular se tramitarán el 19/08/2024.
Cerramos del 10/08 al 18/08. Los pedidos cursados a partir del 09/08 a las 12.00 hora de España peninsular se tramitarán el 19/08/2024.
  1. Libros
  2. Linux
  3. Shell Bash
Extrait - Linux Principios básicos de uso del sistema (8ª edición)
Extractos del libro
Linux Principios básicos de uso del sistema (8ª edición)
2 opiniones
Volver a la página de compra del libro

Shell Bash

Introducción

A pesar de la existencia de interfaces gráficas cada vez más fáciles de utilizar y ergonómicas, el uso de la línea de comandos sigue siendo frecuente en Linux.

El aprendizaje del shell permite al lector comprender mejor el funcionamiento del sistema y aumentar su productividad al facilitarle el uso de este.

Este capítulo pasa revista a diferentes funcionalidades ofrecidas por el shell Bash.

Generalidades y definiciones

El shell

El shell es el programa que se ejecuta automáticamente cuando un usuario se conecta al sistema en un terminal de texto y establece el vínculo entre el usuario y el sistema.

images/0901shel.png

El término "shell" en inglés significa "concha", lo que se corresponde con la imagen de encapsulación que realmente representa.

El shell se llama también "intérprete de comandos" porque:

  • Es el que traduce al sistema las instrucciones indicadas por el usuario mediante la línea de comandos y el que presenta la información devuelta en la pantalla.

  • A diferencia de un compilador utilizado en programación (que construye un archivo binario comprensible por el núcleo Linux a partir de una serie de instrucciones contenidas en el código fuente), el shell interpreta y ejecuta cada comando a medida que el usuario los escribe.

Existen muchos shells disponibles para Linux; destacan:

  • Bourne Shell o sh: es el primer shell escrito para Unix por Steve Bourne. Hoy, aunque obsoleto, ha quedado como el shell de referencia en Unix, y muchos intérpretes de comandos recientes conservan la compatibilidad con él. El programa correspondiente en Linux es sh o bsh.

  • Korn Shell o KSH: es uno de los intérpretes de comandos más utilizados en el mundo Unix. Es compatible con el shell Bourne original.

  • C Shell :este shell fue desarrollado por la rama...

Variables

Verdadero lenguaje de programación, el shell Bash proporciona todos los elementos necesarios para desarrollar aplicaciones; esta sección trata sobre las variables.

Una variable es un parámetro que puede cambiar durante la ejecución de un programa; se le da un nombre para recuperar el valor que representa.

1. Trabajo con variables

Asignación de nombre

El nombre de una variable es una palabra compuesta exclusivamente por caracteres alfanuméricos y el subrayado _ (underscore), que empieza por una letra o un subrayado.

Por convención, el usuario nombrará a las variables con caracteres en minúsculas porque las mayúsculas se emplean generalmente para los nombres de variables de entorno.

Como en los nombres de archivo, es preferible dar nombres explícitos a las variables para facilitar el mantenimiento de los scripts generados.

Asignación

Una variable llamada var puede recibir un valor valor por una asignación de la forma var=valor.

No hay ningún espacio antes ni después del carácter = y si el valor se compone de varias palabras o caracteres especiales, debe ir enmarcado entre caracteres de cita (véase sección Caracteres de cita en este capítulo).

Una variable existe desde que se le asigna un valor; este valor puede ser un número, una palabra o una cadena de caracteres con cualquier carácter especial:

[javier]$ var1=12 
[javier]$ var2=palabra 
[javier]$ var3="dos palabras" 
[javier]$ var4='car. especiales: $* ?{}()[]"\&~|`^!=%,.;#' 

Si no se proporciona ningún valor, la variable recibe una cadena vacía; las dos sintaxis siguientes son equivalentes:

[javier]$ var5="" 
[javier]$ var6= 

Llamada y visualización

El shell reemplaza una variable por su valor si su nombre precedido por el carácter $ aparece en la línea de comandos, antes incluso de interpretar el comando escrito:

[javier]$ echo $var2 
palabra 

La interpretación de la línea de comandos por parte del shell se efectúa en dos etapas:

images/09-01.png

La llamada a un nombre de variable no definida no genera errores; el shell se limita a reemplazarla por una cadena...

Caracteres genéricos

Los caracteres genéricos son caracteres especiales dedicados a la escritura de motivos en los nombres de archivo.

Permiten efectuar una búsqueda según un motivo por los nombres de archivo presentes en el directorio actual.

Los ejemplos de esta sección se basan en un directorio con los archivos siguientes: 

[javier]$ ls -a 
.   banco   azul       arch1  arch2.4    .os      rosado 
..  blanco  ejemplos   arch2  arch2.7    redonda  rojo 

El asterisco: *

Cuando el Bash encuentra este carácter en la línea de comandos, lo sustituye por una cadena de caracteres (que puede ser de longitud nula) para enumerar todos los nombres de archivo que corresponden al motivo en el directorio actual.

Así, el motivo r*o se reemplaza por todos los nombres de archivo que empiezan por el carácter r y terminan con el carácter o:

[javier]$ ls r*o 
rosado rojo 

El signo * reemplaza cualquier carácter en el motivo, excepto el . (punto) en primera posición en el nombre de archivo; por ejemplo, el motivo *s corresponde al archivo ejemplos, pero no al archivo .os:

[javier]$ ls *s 
ejemplos 

La exclusión del primer punto por el carácter genérico * evita la supresión de archivos ocultos con el comando rm *; el objetivo de los nombres de archivo que empiezan por un punto es precisamente ocultar los archivos de los que uno no se quiere preocupar (pero sin suprimirlos).

Un motivo puede estar compuesto por varios caracteres genéricos; repitiendo el asterisco, se obtiene, por ejemplo, *e* que concuerda con todos los archivos con al menos una e en su nombre:

[javier]$ ls *e* 
ejemplos redonda 

Finalmente, si el shell no encuentra correspondencias con el motivo entre los nombres de archivo presentes en el directorio actual, dicho motivo se transmite tal cual al comando:

[javier]$...

Caracteres de cita

Los caracteres de cita se utilizan para modificar la interpretación del shell de otros caracteres. Así, un carácter especial puede interpretarse literalmente, y no de forma simbólica.

Esto permite que ciertos programas y utilidades reinterpreten o extiendan los caracteres especiales pasados en la línea de comandos sin que los interprete el propio shell.

Los comandos grep y find,descritos más adelante, usan en particular caracteres de cita.

Los apóstrofes: ’

El shell ignora todos los caracteres especiales escritos entre apóstrofes.

Por ejemplo:

[javier]$ echo variable $HOME y asterisco * 
variable /home/javier y asterisco banco blanco azul ejemplos arch1 
arch2 arch2.4 arch2.7 redonda rosado rojo 
[javier]$ echo 'variable $HOME y asterisco *' 
variable $HOME y asterisco * 

Las comillas: "

Como ocurre con los apóstrofes, todos los caracteres especiales entre comillas se ignoran, exceptuando $, ` (acento abierto) y \:

[javier]$ echo "variable $HOME y asterisco *" 
variable /home/javier y asterisco * 

La barra invertida: \

Todo carácter que sigue a la barra invertida pierde su significado especial:

[javier]$ echo \variable \$HOME y asterisco \* 
variable /home/javier y asterisco * 

La barra invertida no produce ningún efecto si el carácter siguiente no es un carácter especial.

El uso de los caracteres de cita permite...

Redirecciones

1. Descriptores de archivos

Cualquier proceso ejecutado en Linux se asocia a tres descriptores de archivos que permiten administrar las entradas, las salidas y los errores estándar.

Se llama descriptor de archivo a un puntero hacia un archivo. Un programa que accede a un archivo para leer o escribir en él datos, primero tiene que asociar (mediante una llamada al sistema) un descriptor de archivo al archivo; a continuación, usa el descriptor como punto de entrada (lectura) o de salida (escritura) para los datos que debe tratar.

Se llama "entradas" a los parámetros tratados por el proceso, y "salidas", a los resultados obtenidos. Los "errores" corresponden a un resultado proveniente de un error de tratamiento por parte del proceso. Los tres descriptores de archivo correspondientes también se identifican por un número: 0 para la entrada, 1 para la salida y 2 para el error:

images/0905red1.png

Por ejemplo, si se considera la operación "8 dividido por 2", un proceso que efectúe este cálculo presentará en entrada la operación que se debe realizar, "8/2", y en salida el resultado, "4":

images/0906red2.png

Si ahora se da la operación "5/0" al mismo proceso, devolverá en error un mensaje que indica que no se permite una división por cero:

images/0907red3.png

Los dispositivos en Linux se representan por archivos en el directorio /dev, y los tres descriptores de archivo asociados de modo predeterminado a un proceso son:

  • el teclado como entrada estándar para que el usuario pueda escribir los datos y parámetros que se deben tratar;

  • el terminal en salida estándar para mostrar los resultados del comando;

  • el terminal como error estándar para que el usuario sea informado de que se ha producido un error de tratamiento.

Estos descriptores pueden redefinirse; se llama a esta operación "redirección".

2. Redirección de la entrada estándar

Para redirigir la entrada estándar de un proceso de modo que no trate los datos desde el teclado, sino desde el contenido de un archivo, se usa el carácter < seguido del nombre del nuevo archivo al que debe apuntar el descriptor de archivo de entrada.

La entrada de un comando finaliza cuando todos los datos del archivo correspondiente se han leído; cuando la entrada es el teclado (predeterminado, sin redirección), se puede notificar...

Alias

El conjunto de redirecciones vistas en este capítulo muestra la lógica de Unix en la disponibilidad de herramientas atómicas (dedicadas a una sola función). Estas pueden asociarse para formar comandos más complejos y adaptados a las necesidades del usuario.

Sin embargo, ciertas líneas de comandos pueden alargarse rápidamente y un uso frecuente de esta sintaxis pronto puede resultar desagradable. Pero es posible simplificar el trabajo del usuario definiendo alias de comandos.

Un alias está compuesto por un nombre (generalmente simple) que será reemplazado por un comando (generalmente complejo o largo).

La lista de alias existentes puede conseguirse ejecutando el comando alias sin argumentos:

[javier]$ alias 
alias cd..='cd ..' 
alias cp='cp -i' 
alias d='ls' 
alias df='df -h -x supermount' 
alias du='du -h' 
alias kde='xinit /usr/bin/startkde'  
alias l='ls' 
alias la='ls -a' 
alias ll='ls -l' 
alias ls='ls -F --color=auto' 
alias lsd='ls -d */' 
alias mc='. /usr/share/mc/bin/mc-wrapper.sh' 
alias md='mkdir' 
alias mv='mv -i' 
alias p='cd -' 
alias rd='rmdir' 
alias rm='rm -i' 
alias s='cd ..' 

Se llama a un alias como a cualquier otro comando:...

Ejecución de comandos

Los comandos escritos por el usuario pueden ser de diferentes naturalezas:

  • alias;

  • comando interno;

  • comando externo.

1. Comandos internos del shell

Se califican como internos los comandos integrados en el shell. Su ejecución no genera subprocesos.

Los comandos internos se componen esencialmente de herramientas que permiten modificar el entorno del shell: cambio del directorio actual (cd), definición de variables (set, unset, etc.) y de alias (alias, unalias), estructuras de control (if, for, while, etc.), etc.

La lista exhaustiva de comandos internos incluidos en el shell Bash es: :, ., alias, bg, bind, break, builtin, caller, case, cd, command, compgencomplete, compopt, continue, coproc, declare, dirs, disown, echo, enable, eval, exec, exit, export, false, fc, fg, for, functiongetopts, hash, help, history, if, jobs, kill, let, locallogout, mapfile, popd, printf, pushd, pwd, read, readarrayreadonly, return, select, set, shift, shopt, source, suspend, test, time, trap, true, type, typeset, ulimit, umask, unalias, unset, until, wait, while.

La página del manual de Bash (man bash) detalla los comandos internos que no se estudian en esta obra.

2. Comandos externos

Los comandos externos agrupan todos los archivos ejecutables presentes en el sistema de archivos. Su ejecución genera un proceso hijo del shell que ha interpretado el comando.

El archivo binario o el script asociado a un comando debe estar...

Sustitución de comandos

La sustitución de comandos consiste en recuperar la salida de un comando en la línea de comandos. Las salidas de comandos pueden utilizarse para la asignación de una variable o como argumento de otro comando.

El shell efectúa las sustituciones de comandos antes de interpretar la línea de comandos en su totalidad.

La sintaxis clásica de una sustitución de comandos utiliza el apóstrofe invertido (o acento abierto, o "back quote") obtenido con la tecla [`]+[espacio] en un teclado español:

[javier]$ whoami 
javier 
[javier]$ echo "mi login es 'whoami'" 
mi login es javier 
[javier]$ milogin='whoami' 
[javier]$ echo "mi login es $milogin" 
mi login es javier 

La ventaja de asignar la salida de un comando a una variable radica en poder reutilizar varias veces el resultado evaluando una sola vez el comando.

La segunda sintaxis admitida para la sustitución de comandos es $(). La ventaja de esta sintaxis reside en poder anidar las sustituciones de comandos:

[javier]$ echo 'contenido de mi directorio: $(ls /home/$(whoami))' 
contenido de mi directorio: blanco 
azul 
amarillo 
marrón 
rojo 
verde 
violeta 

Opciones del shell Bash

El comportamiento del shell Bash puede modificarse con la activación de opciones. 

La sintaxis general, para activar una opción, es: set -o opción. Para desactivar una opción, utilice set +o opción.

Aunque parezca poco lógico -porque el signo menos es el carácter previsto inicialmente para introducir las opciones de comandos en Unix- aquí se usa el + para la desactivación.

El estado de las distintas opciones del shell puede visualizarse mediante el comando set -o solo:

[javier]$ set -o  
allexport              off  
braceexpand            on  
emacs                  on  
errexit                off  
errtrace               off  
functrace              off  
hashall                on  
histexpand             on  
history                on  
ignoreeof              off  
interactive-comments   on  
keyword                off  
monitor      ...

Ejercicios

Ejercicio 1

Muestre con un solo comando todos los archivos presentes en la carpeta /etc cuyo nombre comience por la letra p, o termine por la letra d precedida por un punto.

Solución

Debemos emplear los caracteres genéricos para crear el patrón correspondiente al enunciado:

[javier]$ ls -d /etc/{p*,*.d}  
/etc/bash_completion.d   /etc/passwd          /etc/purple  
/etc/binfmt.d            /etc/passwd-         /etc/rc0.d  
/etc/chkconfig.d         /etc/passwdqc.conf   /etc/rc1.d  
/etc/cron.d              /etc/pcmcia          /etc/rc2.d  
/etc/depmod.d            /etc/pinforc         /etc/rc3.d  
/etc/dnsmasq.d           /etc/pkcs11          /etc/rc4.d  
/etc/dracut.conf.d       /etc/pki             /etc/rc5.d  
/etc/exports.d           /etc/plymouth        /etc/rc6.d  
/etc/gdbinit.d           /etc/pm              /etc/rc.d  
/etc/grub.d              /etc/polkit-1        /etc/request-key.d  ...