Home Wiki > Bash
Sign up | Login

Bash

tagline: De openSUSE

Bash es una consola de comandos Unix escrita para el proyecto GNU. Su nombre es un acrónimo de Bourne-again shell —que es un juego de palabras (Bourne again / born again / Renacimiento) de la shell Bourne (sh), que fue una shell importante de Unix, en sus primeros tiempos. La shell Bourne fue la shell distribuida con la Version 7 de Unix. La shell Bourne original fue escrita por Stephen Bourne, por entonces investigador de los laboratorios Bell. La consola Bash fue escrita en 1987 por Brian Fox. En 1990, Chet Ramey se convierte en el mantenedor principal. Bash es la consola por defecto en la mayoría de sistemas Linux, como openSUSE.

Características de la sintaxis de Bash

La sintaxis de comandos de Bash es un superconjunto de la sintaxis de comandos de la shell Bourne. La especificación definitiva de la sintaxis de comandos de Bash es el Bash Reference Manual Enlace en inglés distribuido por el proyecto GNU. Esta sección destaca algunas de las características únicas de la sintaxis de Bash.

La amplia mayoría de los scripts Bourne pueden ser ejecutados sin modificaciones por Bash, con la excepción de aquellos scripts Bourne que hagan referencia a una variable especial de la shell Bourne o usen un comando interno de la misma. La sintaxis de comandos de Bash incluye ideas recogidas de las shell Korn (ksh) y C (csh), como la edición de la línea de comandos, el histórico de comandos, la pila de directorios, las variables $RANDOM y $PPID, y la sintaxis POSIX de sustitución de comandos: $(...). Cuando se usa en modo interactivo, Bash soporta el completado de nombres de programas parcialmente escritos, nombres de ficheros, nombres de variables, etc. simplemente pulsando la tecla del tabulador (TAB).

La sintaxis de Bash cuenta con muchas extensiones de las que carece la sintaxis de la shell Bourne. Algunas de estas extensiones están enumeradas aquí.

Matemáticas con enteros

Una limitación importante de la shell Bourne es que no puede desarrollar cálculos de enteros sin lanzar para ello un proceso externo. Bash puede realizar directamente cálculos con enteros usando el comando ((...)) y la sintaxis de variables $[...], así:

VAR=55             # Asigna el valor entero 55 a la variable VAR.
((VAR = VAR + 1))  # Suma uno a la variable VAR. Nota la ausencia del carácter '$'.
((++VAR))          # Otra forma de sumar uno a VAR. Imita el preincremento al estilo C.
((VAR++))          # Otra forma más de sumar uno a VAR. Imita el postincremento al estilo C.
echo $[VAR * 22]   # Multiplica VAR por 22 y sustituye el resultado dentro del comando.
echo $((VAR * 22)) # Otra forma de hacer lo mismo.

El comando ((...)) también puede ser usado en sentencias condicionales, porque su código de salida es 0 ó 1 dependiendo de que la condición sea verdadera o falsa:

if ((VAR == Y * 3 + X * 2))
then
       echo Yes
fi
((Z > 23)) && echo Yes

El comando ((...)) soporta los siguientes operadores relacionales: '==', '!=', '>', '<', '>=', y '<='.

Bash no puede desarrollar directamente cálculos de coma flotante. Las únicas shell de Unix capaces de esto son Korn Shell (versión de 1993) y zsh (desde la versión 4.0).

Redirección de entrada/salida

Bash implementa varias sintaxis de redirección de entrada/salida de las que carece la shell Bourne. Bash puede redirigir la salida estándar y el error estándar a un tiempo usando esta sintaxis:

comando &> archivo

lo que resulta más simple de escribir que la sintaxis equivalente para Bourne, "comando > archivo 2>&1". Bash, desde la versión 2.05b, puede redirigir la entrada estándar desde una cadena usando la siguiente sintaxis:

comando <<< "cadena a ser leída como entrada estándar"

Si la cadena contiene espacios en blanco, debe entrecomillarse.

Ejemplo: Redirigir la salida estándar a un archivo, escribir datos, cerrar archivo, resetear la salida estándar

# make Filedescriptor(FD) 6 a copy of stdout (FD 1)
exec 6>&1
# abrir el archivo "test.data" en modo escritura
exec 1>test.data
# producir algún contenido
echo "data:data:data"
# cerrar archivo "test.data"
exec 1>&-
# make stdout a copy of FD 6 (reset stdout)
exec 1>&6
# cerrar FD6
exec 6>&-

Abrir y cerrar archivos

# abrir archivo test.data en modo lectura
exec 6<test.data
# leer el archivo hasta el final
while read -u 6 dta
do
  echo "$dta" 
done
# cerrar archivo test.data
exec 6<&-

Recoger la salida de comandos externos

# ejecutar 'find' y almacenar los resultados en VAR
# buscar nombres de archivos que acaban con la letra "h"
VAR=$(find . -name "*h")


Expresiones regulares

Bash 3.0 soporta la búsqueda en proceso de coincidencias mediante expresiones regulares usando la siguiente sintaxis, en semejanza con Perl:

[[ cadena =~ expresión-regular ]]

La sintaxis de expresiones regulares es la misma que está documentada en la página man regex(3). El código de salida del comando anterior será 0 si la expresión coincide con la cadena, o 1 si no coincide. Las subexpresiones entre paréntesis en la expresión regular puede ser accedidas usando la variable BASH_REMATCH de la shell, tal como sigue:

if [[ abcfoobarbletch =~ 'foo(bar)bl(.*)' ]]
then
        echo ¡La expresión coincide!
        echo $BASH_REMATCH      -- produce la salida: foobarbletch
        echo ${BASH_REMATCH[1]} -- produce la salida: bar
        echo ${BASH_REMATCH[2]} -- produce la salida: etch
fi

Esta sintaxis aporta un rendimiento superior a lanzar un proceso separado que ejecute un comando grep, porque la búsqueda de la expresión regular tiene lugar dentro del proceso Bash. Si la expresión regular o la cadena contienen espacios en blanco o caracteres especiales de la shell (como '*' o '?'), deben entrecomillarse.

Escapado de caracteres con Backslash

Las expresiones en la forma $'cadena' son tratadas de forma especial. La expresión se expande a una cadena, con los caracteres escapados sustituidos tal como se especifica en el lenguaje de programación C. Las secuencias de escape, de encontrarse, se decodifican de esta manera:

Backslash Escapes
Escape
Backslash
Se expande a ...
\a Un carácter de alerta (bell)
\b Un carácter backspace
\e Un carácter de escape
\f Un carácter de avance de página
\n Un carácter de nueva línea
\r Un carácter de retorno de carro
\t Un carácter de tabulado horizontal
\v Un carácter de tabulado vertical
\\ Un carácter de barra invertida
\' Un carácter de comilla simple
\nnn El carácter de 8 bits cuyo valor es el valor octal nnn (de uno a tres dígitos)
\xHH El carácter de 8 bits cuyo valor es el valor hexadecimal HH (uno o dos dígitos hexadecimales)
\cx Un carácter control-X


El resultado expandido se enmarca entre comillas simples, como si no existiera el símbolo del dólar.

Una cadena entre comillas dobles precedida del símbolo del dólar ($"...") causará que la cadena se traduzca de acuerdo al LOCALE actual. Si el locale actual es C o POSIX, el símbolo del dólar se ignora. Si la cadena es traducida y reemplazada, esta se enmarcará con comillas dobles.

Scripts de inicio Bash

Cuando arranca Bash, ejecuta los comandos de ciertos scripts.

Cuando se invoca a Bash como una consola de login interactiva, o como una consola no interactiva con el parámetro --login, en primer lugar lee y ejecuta los comandos presentes en el archivo /etc/profile, si existe. Luego busca los archivos ~/.bash_profile, ~/.bash_login, y ~/.profile, en este orden, y lee y ejecuta los comandos partiendo del primero que exista y sea legible. El parámetro --noprofile se puede usar cuando la shell está arrancada para inhibir este comportamiento.

Cuando existe una consola de login, Bash lee y ejecuta los comandos del archivo ~/.bash_logout, si existe.

Cuando se arranca una shell interactiva que no es una shell de login, Bash lee y ejecuta los comandos de ~/.bashrc, si existe. Esto puede descartarse mediante el parámetro --norc. El parámetro --rcfile archivo, en cambio, forzará a Bash a leer y ejecutar los comandos del archivo citado, en vez de ~/.bashrc.

Cuando se inicia Bash de forma no interactiva, para ejecutar un shell script, por ejemplo, busca la variable BASH_ENV en el entorno, expande su valor si lo tiene, y usa dicho valor como el nombre de un archivo a leer y ejecutar. Bash se comporta como si ejecutáramos lo siguiente:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

pero no usa el valor de la variable PATH para buscar el nombre del archivo.

Si Bash se invoca con el nombre sh, intenta imitar el comportamiento de arranque de las versiones antiguas de sh tanto como sea posible, mientras se respete el estándar POSIX. Cuando se invoca como una shell de login interactiva, o como una no interactiva mediante el parámetro --login, primero intenta leer y ejecutar los comandos presentes en /etc/profile y ~/.profile, en ese orden. El parámetro --noprofile se usa para evitar esto. Cuando se invoca como una shell interactiva con el nombre sh Bash busca la variable ENV, expande su valor si está definido, y lo usa como el nombre de un archivo a leer y ejecutar. Desde una shell invocada como sh no intenta ejecutar comandos desde ningún otro archivo de arranque, el parámetro --rcfile queda sin efecto. De la misma forma, una shell no interactiva invocada con el nombre sh no intenta leer ningún otro archivo de arranque. Cuando se invoca como sh, Bash entra en modo posix después de leer los archivos de arranque.

Cuando se inicia Bash en modo posix, o si se arranca con el parámetro --posix, sigue el estándar POSIX de scripts de arranque. En este modo, las shell interactivas expanden la variable ENV y los comandos se leen y ejecutan desde el archivo cuyo nombre sea el del valor expandido. No se leerá ningún otro archivo de arranque.

Bash intenta determinar cuando está siendo arrancada por un demonio de shell remoto, como rshd. Si Bash determina que está siendo arrancada de este modo, leerá y ejecutará las órdenes de ~/.bashrc, si es que el archivo existe y es legible, pero no lo hará si es invocada como sh. El parámetro --norc puede usarse para evitar este comportamiento, y el parámetro --rcfile archivo se puede usar para forzar la lectura de otro archivo, pero rshd no suele invocar la shell con estos parámetros ni permite que se especifiquen.

Enlaces externos

Guías de Bash del Linux Documentation Project:

Otras guías y tutoriales: