Guía completa sobre estructuras especiales, variables especiales y expansiones en Bash

Descripción general

Este artículo resume de forma sistemática todas las estructuras especiales, variables, expansiones y construcciones de control utilizadas en el shell Bash.


Sobre la notación de variables

Los valores dinámicos o dependientes del entorno se expresan como <<nombre_variable>> y se muestran con ejemplos concretos.

Variable Ejemplo Descripción
<<var>> name, path, user Nombre de variable arbitrario
<<default>> guest, 8080 Valor por defecto o alternativo
<<pattern>> *.txt, */ Patrón de nombre o cadena
<<offset>> 0, 3 Posición inicial del substring (base 0)
<<length>> 4, 10 Longitud del substring
<<prefix>> ENV_, HOST Coincidencia inicial del nombre
<<index>> 0, 1, 2 Índice o clave en un array/asociativo
<<file>> /tmp/test.txt Ruta de archivo

Paso 1: Caracteres especiales (metacaracteres)

Símbolo Significado Ejemplo
* Coincide con cualquier cadena ls *.txt → lista todos los .txt
? Coincide con un solo carácter ls ?.sha.sh, b.sh, etc.
[a-z] Rango de coincidencia ls [A-Z]* → archivos en mayúscula
{a,b} Expansión de llaves mv {hoge,huga}
{1..3} Rango numérico touch file{1..3}.txt
$ Expansión de variable echo $HOME
! (negación) Operador lógico de negación [[ ! -f test.txt ]]
! (historial) Expansión de comando previo !10 → ejecuta el comando n.º 10
~ Directorio home cd ~
; Encadenamiento de comandos pwd; ls
&& Ejecuta si el anterior tuvo éxito make && echo OK
` `
& Ejecución en background sleep 5 &
` ` Pipe
> Redirección de salida echo hi > out.txt
>> Añadir al final echo hi >> out.txt
< Redirección de entrada wc -l < file.txt
() Subshell (cd /tmp; ls)
{} Ejecución en el mismo shell { echo A; echo B; }
\ Escape echo \$HOME
' ' Literal sin expansión echo '$USER'
" " Con expansión echo "$USER"

Paso 2: Variables especiales

Variable Contenido Ejemplo
$0 Nombre del script echo $0script.sh
$1〜$9 Argumentos echo $1
$@ Todos los argumentos for a in "$@"; do echo $a; done
$# Número de argumentos echo $#
$? Código de salida del comando previo ls /nope; echo $?
$$ PID actual echo $$
$! PID del último proceso en background sleep 10 & echo $!
$- Opciones del shell actual echo $-
$_ Último argumento del comando anterior echo $_
$PPID PID del proceso padre echo $PPID
$RANDOM Número aleatorio 0–32767 echo $RANDOM
$SECONDS Segundos desde el inicio del shell echo $SECONDS
$FUNCNAME Nombre de la función actual myf(){ echo $FUNCNAME; }; myf
$PIPESTATUS[@] Códigos de salida en un pipe `ls

Paso 3: Expansión de variables (Parameter Expansion)

Sintaxis Significado Ejemplo
${<<var>>} Expansión simple name=user; echo ${name}
${<<var>>:-<<default>>} Usa valor por defecto si está indefinida echo ${user:-guest}
${<<var>>:=<<default>>} Asigna valor por defecto echo ${port:=8080}
${<<var>>:+alt} Usa alt si está definida x=1; echo ${x:+OK}
${<<var>>:?msg} Error si no está definida echo ${config:?missing}
${#<<var>>} Longitud de la cadena name=user; echo ${#name}
${<<var>>%<<pattern>>} Elimina patrón más corto al final path=/a/b/c; echo ${path%/*}
${<<var>>%%<<pattern>>} Elimina patrón más largo al final echo ${path%%/*}
${<<var>>#<<pattern>>} Elimina patrón más corto al inicio echo ${path#*/}
${<<var>>##<<pattern>>} Elimina patrón más largo al inicio echo ${path##*/}
${<<var>>/<<pattern>>/<<repl>>} Sustituye primera coincidencia echo ${msg/foo/bar}
${<<var>>//<<pattern>>/<<repl>>} Sustituye todas echo ${msg// /_}
${<<var>>:<<offset>>} Subcadena desde posición s=abcdef; echo ${s:2}
${<<var>>:<<offset>>:<<length>>} Subcadena con longitud echo ${s:1:3}
${!<<prefix>>*} Lista de variables por prefijo HOST1=x; echo ${!HOST*}
${!<<var>>} Referencia indirecta ref=NAME; NAME=user; echo ${!ref}
${<<var>>^^} / ${<<var>>,} Mayúsculas/minúsculas n=abc; echo ${n^^}
${<<var>>@Q} Expansión entrecomillada x='abc'; echo ${x@Q}

Paso 4: Arrays y arrays asociativos

# Array normal
arr=(a b c)
echo ${arr[<<index>>]}
echo ${#arr[@]}
for i in "${arr[@]}"; do echo $i; done

# Array asociativo
declare -A map
map[<<index>>]=100
map[name]=user
echo ${map[<<index>>]}
echo ${!map[@]}

Paso 5: Expansión aritmética

x=5
y=3
echo $((x + y))
((x *= 2))
echo $x

Paso 6: Condicionales y comparaciones

# Cadenas
if [ "$USER" = "root" ]; then echo root; fi

# Números
if [ "$x" -lt 10 ]; then echo "small"; fi

# Archivos
if [ -f /etc/passwd ]; then echo "exists"; fi

# Expresión regular
s="hello123"
[[ $s =~ [0-9]+ ]] && echo "contains number"

Paso 7: Sustitución de comandos y subshell

echo "Hoy es: $(date +%Y-%m-%d)"
(cd /tmp; ls)

Paso 8: Redirección y descriptores de archivo (FD)

echo "Hola" > <<file>>
echo "Append" >> <<file>>
wc -l < <<file>>
ls /notfound 2> err.log
echo "Error" >&2
exec 3> custom.log
echo "via fd3" >&3
exec 3>&-

Descriptores de archivo (FD)

FD Nombre Descripción Ejemplo
0 stdin Entrada estándar < file.txt
1 stdout Salida estándar echo test > out.txt
2 stderr Errores ls /nope 2> err.log
3+ FD personalizados Streams definidos por el usuario exec 3> log.txt

FD3 es un descriptor definido por el usuario. Ejemplo:

exec 3> process.log
echo "Inicio" >&3
exec 3>&-

Paso 9: Trampas y control de errores

set -e
set -u
set -x
set -o pipefail

trap 'echo Finalizado' EXIT
trap 'echo Error' ERR

Paso 10: Control de trabajos

sleep 10 &
jobs
fg %1
bg %1
disown %1
kill %1

%1 hace referencia al número de trabajo mostrado por jobs.


Paso 11: Comandos y palabras reservadas

:
true
false
source ~/.bashrc
eval "echo ejecutado"
{ echo A; echo B; }

Conclusión

Esta guía abarca de forma completa los símbolos, variables, expansiones y estructuras de control en Bash.
Comprender estos mecanismos permite diseñar scripts más seguros, portables y eficientes para automatización avanzada en entornos Linux.