Variables en el Shell
Tipos de Variables
Variables Locales
Una varible local se define y es accesible únicamente dentro de la sesión de shell actual donde fue creada. Si se inicia un nuevo subshell, esta variable no estará disponible.
$ usuario=datos
$ echo $usuario
datos
Variables de Entorno
Las variables de entorno son heredables por los procesos hijos. Para crear o convertir una variable local en una de entorno, se utiliza el comando export.
$ export usuario
$ env | grep usuario
usuario=datos
Modificación y Uso Clave
La variable PATH es un ejemplo crítico. Define los directorios donde el sistema buscará ejecutables al escribir un comando. Agregar un directorio a PATH permite ejecutar scripts desde cualquier ubicación.
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
$ PATH=$PATH:/home/usuario/scripts
$ mi_script # Ejecutable ahora si tiene permisos
Referenciando Variables
Para interpolar variables, se usa el signo $. Las llaves {} son útiles para delimitar el nombre de la variable cuando está concatenada con texto. La sustitución de comando $() permite asignar la salida de un comando a una variable.
$ prefijo="SRV"
$ nombre_completo=${prefijo}01
$ echo $nombre_completo
SRV01
$ fecha_actual=$(date +%F)
$ echo $fecha_actual
2024-06-15
Visualización y Eliminación
El comando set muestra todas las variables (locales y de entorno), mientras que env solo muestra las de entorno. Para eliminar una variable, se usa unset.
$ set | grep -c "="
42
$ env | grep -c "="
25
$ unset usuario
$ echo $usuario
# (Salida vacía)
Interacción con el Usuario
Parámetros Posicionales
Los argumentos pasados a un script se reciben como $1, $2, etc. Otros parámetros especiales son:
$0: Nombre o ruta del script en ejecución.$#: Número total de argumentos recibidos.$?: Estado de salida (exit status) del último comando ejecutado (0 indica éxito).
#!/bin/bash
echo "Ejecutando: $0"
echo "Primer argumento: $1"
echo "Tercer argumento: $3"
echo "Total de argumentos: $#
# Salida de ejecución: ./script.sh a b c
# Ejecutando: ./script.sh
# Primer argumento: a
# Tercer argumento: c
# Total de argumentos: 3
Lectura de Entrada (read)
El comando read captura la entrada del usuario. Opciones útiles incluyen -p (mensaje), -s (entrada oculta) y -t (tiempo de espera).
#!/bin/bash
read -p "Ingrese su usuario: " nombre_usuario
echo -n "Contraseña: "
read -s contrasena
echo
read -t 5 -p "Opción [5s]: " seleccion
echo "Usuario: $nombre_usuario, Seleccion: $seleccion"
Pruebas de Condición
Operadores Lógicos
Los operadores && (AND) y || (OR) encadenan comandos basados en su código de salida.
# AND Lógico: La segunda ejecución ocurre si la primera tiene éxito
$ ls /directorio_valido && echo "Existe"
# OR Lógico: La segunda ejecución ocurre si la primera falla
$ ls /directorio_inexistente || echo "No encontrado"
# Uso combinado para un flujo
$ ping -c 1 -W 1 192.168.1.1 > /dev/null 2>&1 && echo "Host activo" || echo "Host inactivo"
Sintaxis de Prueba
Existen varias formas de realizar pruebas de condición. Todas retornan un estado de salida (0 para verdadero, 1 para falso).
# Comando test
$ test 5 -gt 3; echo $?
0
# Corchetes simples [ ]: No soporta operadores lógicos modernos dentro.
$ [ -d /etc -a -f /etc/hosts ]; echo $?
0
$ [ ! -f /archivo_falso ]; echo $?
0
# Doble corchete [[ ]]: Soporta operadores lógicos, coincidencia de patrones y es más robusto.
$ [[ "cadena" == "cadena" && 10 -eq 10 ]]; echo $?
0
$ [[ -d /etc || -f /bin/bash ]]; echo $?
0
Estructuras de Control
Sentencia Condicional (if/elif/else)
#!/bin/bash
# Ejemplo: Verificar tipo de ruta
if [[ -d "$1" ]]; then
echo "$1 es un directorio."
elif [[ -f "$1" ]]; then
echo "$1 es un archivo."
else
echo "$1 no existe o no es un archivo/directorio válido."
fi
Sentencia de Selección (case)
#!/bin/bash
echo "1) Iniciar servicio"
echo "2) Reiniciar servicio"
echo "3) Detener servicio"
read -p "Seleccione una opción: " opcion
case $opcion in
1)
systemctl start httpd
;;
2)
systemctl restart httpd
;;
3)
systemctl stop httpd
;;
*)
echo "Opción no válida."
;;
esac
Bucles (for, while, until)
# for: Itera sobre una lista explícita o generada.
for archivo in /etc/*.conf; do
echo "Procesando: $archivo"
done
# for: Uso de expansión de brace
for i in {1..5}; do
echo "Número: $i"
done
# while: Se ejecuta mientras la condición sea verdadera.
contador=0
while [[ $contador -lt 5 ]]; do
echo "Iteración: $contador"
((contador++))
done
# until: Se ejecuta hasta que la condición sea verdadera (opuesto a while).
intentos=0
until [[ $intentos -ge 3 ]]; do
read -p "Contraseña: " pwd
((intentos++))
done
Control de Flujo en Bucles
# break: Sale del bucle inmediatamente.
for num in {1..10}; do
[[ $num -eq 6 ]] && break
echo $num
done
# continue: Salta a la siguiente iteración del bucle.
for num in {1..10}; do
[[ $((num % 2)) -eq 0 ]] && continue
echo $num # Solo impares
done
Ejecución de Scripts
Los scripts se pueden ejecutar de varias maneras, con implicaciones en permisos y el entorno de shell utilizado:
- Ruta absoluta o relativa: Requiere permisos de ejecución (
chmod +x script.sh). bash script.sh: Invoca el intérprete bash explícitamente, no requiere permisos de ejecución en el archivo.source script.sho. script.sh: Ejecuta los comandos en el shell actual, no crea un subproceso.
# Depuración con traza
bash -x mi_script.sh
# Muestra cada comando y sus argumentos antes de ejecutarlo