Variables en Bash
Las variables son contenedores que almacenan datos (texto, números, rutas de archivos, etc.) y permiten que tus scripts sean dinámicos y reutilizables. En Bash, las variables son fundamentalmente cadenas de texto, pero pueden interpretarse como números según el contexto.
Declaración y Asignación
#!/bin/bash
# Asignación básica (sin espacios alrededor del =)
nombre="Juan"
edad=25
directorio="/home/usuario"
# Usando las variables
echo "Nombre: $nombre"
echo "Edad: $edad años"
echo "Directorio: $directorio"
# Reasignación
nombre="María"
echo "Nuevo nombre: $nombre"
Reglas importantes
- No debe haber espacios alrededor del signo
=
- Los nombres de variables son case-sensitive (
nombre
≠NOMBRE
) - Deben empezar con letra o guión bajo, no con número
- Pueden contener letras, números y guiones bajos
$ ./variables_basicas.sh
Nombre: Juan
Edad: 25 años
Directorio: /home/usuario
Nuevo nombre: María
Expansión de Variables
Bash ofrece varias formas de expandir (acceder al valor de) las variables:
$variable
Forma simple, la más común.
echo $nombre
→ Juan
${variable}
Forma segura, delimita claramente el nombre.
echo ${nombre}_apellido
#!/bin/bash
archivo="documento"
extension="txt"
# Problema: expansión ambigua
echo "Archivo: $archivo.pdf" # ✅ Funciona
echo "Archivo: $archivo_backup" # ❌ Busca variable 'archivo_backup'
# Solución: usar llaves
echo "Archivo: ${archivo}.pdf" # ✅ Funciona
echo "Archivo: ${archivo}_backup" # ✅ Funciona
# Concatenación de variables
ruta_completa="${HOME}/${archivo}.${extension}"
echo "Ruta completa: $ruta_completa"
# Variables en strings
mensaje="El usuario $USER tiene $((RANDOM % 100)) puntos"
echo "$mensaje"
Comillas: Simples vs Dobles
El tipo de comillas afecta cómo Bash interpreta las variables:
#!/bin/bash
nombre="Juan"
fecha=$(date)
# Comillas dobles: permite expansión
echo "Hola $nombre, hoy es $fecha"
# Salida: Hola Juan, hoy es Tue Oct 15 14:30:25 UTC 2024
# Comillas simples: literal (sin expansión)
echo 'Hola $nombre, hoy es $fecha'
# Salida: Hola $nombre, hoy es $fecha
# Sin comillas: expansión + división de palabras
archivo="mi archivo.txt"
ls $archivo # ❌ Bash ve "mi" y "archivo.txt" como argumentos separados
ls "$archivo" # ✅ Correcto
# Casos especiales
echo "El precio es \$25" # Escapar el $
echo "Ruta: \"$HOME/docs\"" # Escapar comillas dentro de comillas
Regla de oro
Siempre usa comillas dobles alrededor de variables, especialmente si pueden contener espacios: "$variable"
Sustitución de Comandos
Puedes capturar la salida de un comando y usarla como valor de una variable:
#!/bin/bash
# Sintaxis moderna (recomendada)
fecha_actual=$(date)
usuarios_conectados=$(who | wc -l)
directorio_actual=$(pwd)
echo "Fecha: $fecha_actual"
echo "Usuarios conectados: $usuarios_conectados"
echo "Directorio: $directorio_actual"
# Sintaxis antigua (funciona pero no se recomienda)
fecha_antigua=`date`
# Comandos anidados
año_actual=$(date +%Y)
respaldo_nombre="backup_${año_actual}_$(date +%m%d_%H%M).tar.gz"
echo "Nombre del respaldo: $respaldo_nombre"
# Asignar a variables para reutilizar
timestamp=$(date +%Y%m%d_%H%M%S)
log_file="/var/log/mi_script_${timestamp}.log"
echo "Archivo de log: $log_file"
$ ./sustitucion_comandos.sh
Fecha: Tue Oct 15 14:30:25 UTC 2024
Usuarios conectados: 2
Directorio: /home/usuario/scripts
Nombre del respaldo: backup_2024_1015_1430.tar.gz
Archivo de log: /var/log/mi_script_20241015_143025.log
Variables de Entorno
Las variables de entorno son variables especiales que el sistema mantiene y que están disponibles para todos los procesos:
#!/bin/bash
echo "=== INFORMACIÓN DEL USUARIO ==="
echo "Usuario actual: $USER"
echo "UID del usuario: $UID"
echo "Directorio home: $HOME"
echo "Shell actual: $SHELL"
echo -e "\n=== INFORMACIÓN DEL SISTEMA ==="
echo "Hostname: $HOSTNAME"
echo "Sistema operativo: $OSTYPE"
echo "Directorio actual: $PWD"
echo "Directorio anterior: $OLDPWD"
echo -e "\n=== CONFIGURACIÓN ==="
echo "PATH: $PATH"
echo "Idioma: $LANG"
echo "Editor por defecto: $EDITOR"
echo -e "\n=== PROCESO ACTUAL ==="
echo "PID del script: $$"
echo "PID del proceso padre: $PPID"
Creando y exportando variables
#!/bin/bash
# Variable local (solo existe en este script)
mi_variable="valor local"
# Convertir en variable de entorno (disponible para subprocesos)
export mi_variable
# o directamente:
export mi_variable_global="valor global"
# Verificar si una variable está exportada
if [[ -v HOME ]]; then
echo "HOME está definida: $HOME"
fi
# Ver todas las variables de entorno
echo "Variables de entorno:"
env | grep "mi_variable"
# Eliminar variable de entorno
unset mi_variable_global
Expansión Avanzada de Parámetros
Bash ofrece técnicas avanzadas para manipular variables:
#!/bin/bash
# Valores por defecto
nombre=${1:-"Usuario Anónimo"} # Si $1 está vacío, usar "Usuario Anónimo"
puerto=${PORT:-8080} # Si PORT no existe, usar 8080
archivo=${CONFIG_FILE:-"/etc/default.conf"}
echo "Nombre: $nombre"
echo "Puerto: $puerto"
echo "Archivo config: $archivo"
# Validar que variables obligatorias existen
base_datos=${DATABASE_URL:?"ERROR: DATABASE_URL es obligatoria"}
# Asignar valor por defecto solo si la variable está vacía
directorio=${WORK_DIR:="/tmp/trabajo"}
# Usar valor alternativo si variable existe y no está vacía
modo=${DEBUG_MODE:+"modo debug activo"}
echo "Modo: ${modo:-"modo normal"}"
Manipulación de strings
#!/bin/bash
ruta="/home/usuario/documentos/archivo.txt"
# Longitud de string
echo "Longitud: ${#ruta} caracteres"
# Extraer substring (posición:longitud)
echo "Substring: ${ruta:6:7}" # "usuario"
# Eliminar desde el final (más corto)
echo "Sin extensión: ${ruta%.*}" # /home/usuario/documentos/archivo
# Eliminar desde el final (más largo)
echo "Solo directorio: ${ruta%/*}" # /home/usuario/documentos
# Eliminar desde el principio (más corto)
echo "Solo nombre: ${ruta##*/}" # archivo.txt
# Eliminar desde el principio (más largo)
echo "Sin /home: ${ruta#/*/}" # usuario/documentos/archivo.txt
# Reemplazar primera ocurrencia
echo "Cambiar usuario: ${ruta/usuario/admin}"
# Reemplazar todas las ocurrencias
texto="one two one three one"
echo "Cambiar 'one' por '1': ${texto//one/1}"
# Reemplazar al inicio
echo "Cambiar ruta base: ${ruta/#\/home/\/opt}"
$ ./manipulacion_strings.sh
Longitud: 34 caracteres
Substring: usuario
Sin extensión: /home/usuario/documentos/archivo
Solo directorio: /home/usuario/documentos
Solo nombre: archivo.txt
Sin /home: usuario/documentos/archivo.txt
Cambiar usuario: /home/admin/documentos/archivo.txt
Cambiar 'one' por '1': 1 two 1 three 1
Cambiar ruta base: /opt/usuario/documentos/archivo.txt
Variables Especiales
Bash proporciona variables especiales automáticas muy útiles:
#!/bin/bash
echo "=== INFORMACIÓN DEL SCRIPT ==="
echo "Nombre del script: $0"
echo "Número de parámetros: $#"
echo "Todos los parámetros: $*"
echo "Todos los parámetros (array): $@"
echo "PID del script: $$"
echo "Código de salida del último comando: $?"
echo -e "\n=== PARÁMETROS INDIVIDUALES ==="
echo "Primer parámetro: $1"
echo "Segundo parámetro: $2"
echo "Tercer parámetro: $3"
echo -e "\n=== INFORMACIÓN ADICIONAL ==="
echo "Opciones de Bash actuales: $-"
echo "PID del último proceso en background: $!"
# Ejemplo práctico
if [ $# -eq 0 ]; then
echo "Uso: $0 [archivo2] [archivo3]"
exit 1
fi
echo "Procesando $# archivos..."
for archivo in "$@"; do
echo "- Procesando: $archivo"
done
Diferencia entre $* y $@
$*
: Une todos los parámetros en una sola cadena$@
: Mantiene los parámetros como elementos separados- Con comillas:
"$*"
vs"$@"
- la diferencia es crucial en bucles
Aritmética con Variables
Aunque Bash trata las variables como strings, puede realizar operaciones aritméticas:
#!/bin/bash
# Declarar variables enteras
declare -i numero1=10
declare -i numero2=5
# Aritmética básica
suma=$((numero1 + numero2))
resta=$((numero1 - numero2))
multiplicacion=$((numero1 * numero2))
division=$((numero1 / numero2))
modulo=$((numero1 % numero2))
echo "Número 1: $numero1"
echo "Número 2: $numero2"
echo "Suma: $suma"
echo "Resta: $resta"
echo "Multiplicación: $multiplicacion"
echo "División: $division"
echo "Módulo: $modulo"
# Operaciones más complejas
potencia=$((numero1 ** 2))
echo "10 al cuadrado: $potencia"
# Incremento y decremento
contador=0
echo "Contador inicial: $contador"
((contador++))
echo "Después de ++: $contador"
((contador += 5))
echo "Después de += 5: $contador"
# Números aleatorios
aleatorio=$((RANDOM % 100 + 1)) # Entre 1 y 100
echo "Número aleatorio: $aleatorio"
# Comparaciones aritméticas (retornan 0 o 1)
resultado=$((numero1 > numero2))
echo "¿$numero1 > $numero2?: $resultado"
$ ./aritmetica.sh
Número 1: 10
Número 2: 5
Suma: 15
Resta: 5
Multiplicación: 50
División: 2
Módulo: 0
10 al cuadrado: 100
Contador inicial: 0
Después de ++: 1
Después de += 5: 6
Número aleatorio: 42
¿10 > 5?: 1
Ejercicios Prácticos
Ejercicio 1: Información del usuario
Crea un script que muestre información personalizada usando variables:
#!/bin/bash
# Obtener información del usuario
usuario_actual="$USER"
directorio_home="$HOME"
shell_actual="$SHELL"
fecha_actual=$(date "+%A, %d de %B de %Y")
hora_actual=$(date "+%H:%M:%S")
tiempo_activo=$(uptime -p 2>/dev/null || uptime | cut -d',' -f1)
# Información del directorio
directorio_actual=$(pwd)
archivos_directorio=$(ls -1 | wc -l)
espacio_usado=$(du -sh . | cut -f1)
# Mostrar información
echo "======================================"
echo " INFORMACIÓN DEL USUARIO"
echo "======================================"
echo "Usuario: $usuario_actual"
echo "Directorio home: $directorio_home"
echo "Shell: ${shell_actual##*/}"
echo "Fecha: $fecha_actual"
echo "Hora: $hora_actual"
echo "Sistema activo: $tiempo_activo"
echo
echo "DIRECTORIO ACTUAL:"
echo "Ubicación: $directorio_actual"
echo "Archivos/carpetas: $archivos_directorio"
echo "Espacio usado: $espacio_usado"
echo "======================================"
Ejercicio 2: Calculadora simple
Script que acepta dos números como parámetros y realiza operaciones:
#!/bin/bash
# Validar parámetros
if [ $# -ne 2 ]; then
echo "Uso: $0 "
echo "Ejemplo: $0 10 5"
exit 1
fi
# Obtener parámetros
num1="$1"
num2="$2"
# Validar que son números
if ! [[ "$num1" =~ ^-?[0-9]+$ ]] || ! [[ "$num2" =~ ^-?[0-9]+$ ]]; then
echo "Error: Ambos parámetros deben ser números enteros"
exit 1
fi
# Realizar operaciones
suma=$((num1 + num2))
resta=$((num1 - num2))
multiplicacion=$((num1 * num2))
# División con validación
if [ $num2 -eq 0 ]; then
division="No definida (división por cero)"
modulo="No definido (división por cero)"
else
division=$((num1 / num2))
modulo=$((num1 % num2))
fi
# Mostrar resultados
echo "========================================="
echo " CALCULADORA BASH"
echo "========================================="
echo "Número 1: $num1"
echo "Número 2: $num2"
echo "---------"
echo "Suma: $num1 + $num2 = $suma"
echo "Resta: $num1 - $num2 = $resta"
echo "Multiplicación: $num1 × $num2 = $multiplicacion"
echo "División: $num1 ÷ $num2 = $division"
echo "Módulo: $num1 % $num2 = $modulo"
echo "========================================="
Ejercicio de práctica
Crea un script que:
- Acepte un nombre de archivo como parámetro
- Extraiga el nombre sin extensión
- Cree un archivo de respaldo con timestamp
- Muestre información sobre el archivo original
¡Intenta combinarlo con todo lo que has aprendido sobre variables!