Estructura de un script: shebang, permisos, ejecución, variables y expansiones
Introducción
Un script de bash es un fichero de texto con una secuencia de comandos. En esta unidad vemos cómo estructurarlo correctamente, cómo ejecutarlo y cómo trabajar con variables y las distintas formas de expansión que ofrece bash.
Shebang — La primera línea
La primera línea de un script indica al sistema operativo qué intérprete debe usarse para ejecutarlo. Se llama shebang (o hashbang) y empieza siempre por #!.
#!/bin/bash ← bash estándar
#!/usr/bin/env bash ← más portable: busca bash en el PATH
#!/bin/sh ← POSIX shell (compatible pero menos potente)
Se recomienda #!/usr/bin/env bash para scripts que se van a ejecutar en diferentes sistemas donde bash
puede estar en rutas distintas.
Permisos y formas de ejecución
# Crear el script
nano mi_script.sh
# Dar permisos de ejecución
chmod +x mi_script.sh
chmod 755 mi_script.sh # rwxr-xr-x
# Ejecutar el script (necesita permiso de ejecución)
./mi_script.sh
# Ejecutar con bash explícito (no necesita permiso de ejecución)
bash mi_script.sh
# Ejecutar en el shell actual (las variables y cambios afectan al shell)
source mi_script.sh
. mi_script.sh
La diferencia clave: ./script.sh lanza un subshell; source script.sh
ejecuta los comandos en el shell actual, por lo que los cambios de variables y cd
sí afectan al entorno actual.
Variables
Asignación y uso:
#!/usr/bin/env bash
NOMBRE="Juan" # sin espacios alrededor del =
EDAD=30
MENSAJE="Hola, $NOMBRE"
echo $NOMBRE
echo "$NOMBRE" # siempre entre comillas para evitar word splitting
echo "Tienes $EDAD años"
# Variables de solo lectura
readonly PI=3.14159
Buenas prácticas con variables:
- Siempre entre comillas dobles al usar:
"$VARIABLE"— evita problemas con espacios. - Convención: variables locales en minúsculas, variables de entorno en mayúsculas.
- No dejar espacios alrededor del
=en la asignación.
Expansiones de variables
Bash ofrece sintaxis avanzada para manipular variables sin necesitar comandos externos.
Expansión básica y con llaves:
FICHERO="informe"
echo $FICHERO
echo {$FICHERO}_2024.txt # sin ambigüedad
echo "{$FICHERO}_final"
Valores por defecto:
# Si VAR no está definida o está vacía, usar "valor_por_defecto"
echo "{$VAR:-valor_por_defecto}"
# Si VAR no está definida, asignarla y usarla
echo "{$VAR:=valor_por_defecto}"
# Si VAR está definida, usar "otro_valor"; si no, cadena vacía
echo "{$VAR:+otro_valor}"
Longitud y subcadenas:
CADENA="Hola Mundo"
echo "{#CADENA}" # longitud: 10
echo "{CADENA:5}" # desde posición 5: "Mundo"
echo "{CADENA:0:4}" # 4 caracteres desde posición 0: "Hola"
Sustitución de patrones:
FICHERO="documento.txt"
echo "{FICHERO%.txt}" # eliminar sufijo .txt → "documento"
echo "{FICHERO#doc}" # eliminar prefijo "doc" → "umento.txt"
echo "{FICHERO/txt/md}" # sustituir primera ocurrencia → "documento.md"
echo "{FICHERO//o/0}" # sustituir todas las ocurrencias → "d0cument0.txt"
Sustitución de comandos
Permite capturar la salida de un comando y usarla como valor.
# Forma moderna (recomendada)
FECHA=$(date +%F)
USUARIO=$(whoami)
LINEAS=$(wc -l < /etc/passwd)
# Forma antigua (funciona pero es menos legible)
FECHA=`date +%F`
echo "Hoy es $FECHA"
echo "Hay $LINEAS usuarios en el sistema"
Aritmética
A=10
B=3
echo $((A + B)) # 13
echo $((A - B)) # 7
echo $((A * B)) # 30
echo $((A / B)) # 3 (división entera)
echo $((A % B)) # 1 (módulo/resto)
echo $((A ** B)) # 1000 (potencia)
# Incremento y decremento
((A++))
((A+=5))
echo $A # 16
# let (forma alternativa)
let "RESULTADO = A * 2"
echo $RESULTADO
Para aritmética con decimales, usar bc:
echo "scale=2; 10 / 3" | bc # 3.33
Tipos de comillas
- Comillas dobles
" ": permiten expansión de variables y sustitución de comandos. Protegen los espacios. - Comillas simples
' ': todo literal, sin ninguna expansión. - Backticks
` `: sustitución de comandos (forma antigua).
VAR="mundo"
echo "Hola $VAR" # Hola mundo (expansión)
echo 'Hola $VAR' # Hola $VAR (literal)
echo "Hola $(echo $VAR | tr a-z A-Z)" # Hola MUNDO