Fundamentos de Shell: Variables, Condicionales y Bucles

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.sh o . 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

Etiquetas: bash shell scripting variables Condicionales bucles

Publicado el 6-27 23:47