Guía Rápida de Bash Scripting

Bash (acrónimo de Bourne Again SHell) es un intérprete de línea de comandos muy popular en sistemas operativos basados en Unix, como GNU/Linux y macOS.

Es la “consola” o “terminal” que utilizamos para interactuar con el sistema operativo a través de comandos de texto.

Cuando hablamos de Bash Scripting, nos referimos a la escritura de pequeños (o grandes) programas, llamados scripts, para automatizar tareas dentro de un entorno Bash.

Aprender Bash Scripting es muy útil para cualquier persona que trabaje con Linux o macOS: desde desarrolladores y administradores de sistemas, hasta científicos de datos o entusiastas de la informática.

1. Shebang Line

La primera línea de muchos scripts de Bash es la llamada shebang:

#!/bin/bash
  • El #! indica al sistema que el archivo debe ser interpretado por el intérprete de comandos especificado (en este caso, /bin/bash).

  • Es fundamental poner esta línea al inicio de tu script para asegurar que se ejecute con Bash (o el intérprete de tu preferencia).

2. Variables

En Bash, para asignar valores a variables basta con usar el signo = sin espacios alrededor:

username="Jay"
filename=$3
  • username="Jay" almacena una cadena en la variable username.

  • filename=$3 toma el tercer argumento pasado al script y lo asigna a filename.

  • Para acceder al contenido de la variable, utilizamos "$username" o "$filename".

3. Entrada de Usuario (User Input)

Para solicitar datos al usuario, se emplea el comando read:

read -p "Enter your username: " user
echo "Username: $user"
  • read -p "Mensaje" mostrará el mensaje y luego aguardará a que el usuario introduzca un valor.

  • El valor ingresado se almacenará en la variable especificada (user en este ejemplo).

4. Condicional if

Los scripts de Bash permiten ejecutar distintas instrucciones según condiciones definidas:

if [ "$EUID" -ne 0 ]; then
  echo "You are not running this script as the root user."
else
  echo "You are running this script as the root user."
fi
  • [ "$EUID" -ne 0 ] comprueba si el identificador de usuario efectivo (EUID) no es 0, lo que implica que el script no se está ejecutando como root.

  • Si la condición es verdadera, se ejecuta el primer bloque de código; de lo contrario, se ejecuta la cláusula else.

5. Bucles (For Loop)

Los bucles permiten repetir un bloque de instrucciones varias veces. Por ejemplo, para contar hasta 5:

echo "Counting to 5:"
for i in {1..5}; do
  echo "$i"
done
  • {1..5} genera una secuencia de números del 1 al 5.

  • Cada vez que el bucle itera, la variable i toma uno de esos valores.

6. Funciones

En Bash, las funciones se definen para agrupar y reutilizar código:

function greet() {
  echo "Hello, $1!"
}
greet "Alice"
  • function greet() { ... } declara la función greet.

  • $1 se refiere al primer parámetro que se le pasa a la función al invocarla.

  • Al ejecutar greet "Alice", la función imprimirá "Hello, Alice!".

7. Estructura Condicional Case

El comando case es útil para decidir entre varias opciones:

echo "Enter a number between 1 and 2: "
read num
case $num in
  1) echo "You chose one." ;;
  2) echo "You chose two." ;;
  *) echo "Invalid choice." ;;
esac
  • Se evalúa la variable num contra cada patrón.

  • Si coincide con 1, se ejecuta el primer bloque; si coincide con 2, el segundo; de lo contrario, se muestra "Invalid choice."

8. Operaciones con Archivos

Podemos verificar si un archivo existe y si es un directorio con expresiones como -e y -d:

if [ -e "$filename" ] && [ -d "$filename" ]; then
  echo "File exists and is a directory."
else
  echo "File does not exist or is not a directory."
fi
  • -e verifica si el archivo existe.

  • -d comprueba si es un directorio.

9. Argumentos en Línea de Comandos

Al llamar a un script de Bash, se pueden pasar argumentos adicionales que se capturan con $1, $2, $3, etc.:

echo "First argument: $1"
echo "Second argument: $2"
echo "Exit status: $?"
  • $1 se refiere al primer argumento, $2 al segundo, etc.

  • $? representa el exit status del último comando ejecutado.

10. Códigos de Salida (Exit Status Codes)

En Bash, cada comando devuelve un código de salida (exit status) para indicar éxito o error:

cat nonexistent-file.txt 2> /dev/null
echo "Exit status: $?"
  • Si cat no encuentra el archivo, devolverá un código distinto de 0.

  • $? ayuda a comprobar el resultado inmediatamente después de un comando.

11. Arrays Indexados (Indexed Arrays)

Bash permite trabajar con arrays indexados:

fruits=("Apple" "Orange" "Banana")
echo "Fruits: ${fruits[0]}"
  • fruits[0] es "Apple", fruits[1] es "Orange", etc.

  • Para imprimir un elemento específico, se usa ${fruits[indice]}.

12. Arrays Asociativos (Associative Arrays)

Los arrays asociativos permiten usar cadenas como índices:

declare -A capitals
capitals[USA]="Washington D.C"
capitals[France]="Paris"
echo "Capital of France: ${capitals[France]}"
  • Gracias a declare -A, capitals es un array asociativo.

  • Asignamos valores a través de llaves como capitals[USA], capitals[France], etc.

13. Sustitución de Comandos (Command Substitution)

Para capturar la salida de un comando y guardarla en una variable, se utiliza la sintaxis $(comando):

current_date=$(date)
echo "Today's date is: $current_date"
  • $(date) se sustituye por la salida del comando date, asignándola a current_date.

14. Redirecciones en Línea de Comandos

Bash permite redirigir la entrada y salida de los procesos:

echo "This is a sample text." > example.txt
find / -name hello.txt 2> /dev/null
  • > redirige la salida estándar (stdout) a un archivo, sobreescribiéndolo.

  • 2> redirige la salida de errores (stderr) a un archivo o dispositivo (en este ejemplo, /dev/null para desecharla).

15. Operaciones Aritméticas

Puedes realizar operaciones matemáticas usando (( )) o $(( )):

result=$(( 15 * 2 ))
echo $result
  • $(( 15 * 2 )) evalúa la expresión y asigna el resultado a result.

16. Expansión de Parámetros (Parameter Expansion)

La expansión de parámetros se basa en distintas expresiones para manipular variables. Por ejemplo:

SRC="path/to/foo.cpp"
BASEPATH=${SRC%%/*}
echo $BASEPATH
  • ${variable%%/*} elimina lo que coincide con el patrón más extenso a la derecha.

  • Aquí, ${SRC%%/*} cortaría la ruta path/to/foo.cpp quedándose con path.

17. Manejo de Señales (Process Signal Handling)

Bash provee la función trap para capturar señales y ejecutar acciones específicas cuando sucedan:

trap 'echo "Received SIGTERM signal. Cleaning up..."; exit' SIGTERM
  • Cuando el script reciba una señal SIGTERM (por ejemplo, al detener el proceso), se ejecutará el mensaje y luego el script finalizará.

18. Comentarios

Finalmente, en Bash podemos usar:

  • # para comentarios de una sola línea.

  • : ' ... ' o <<COMMENT ... COMMENT para comentarios de varias líneas.

# Esto es un comentario de una sola línea

: '
Esto es un comentario
de múltiples líneas
'

Para los que queráis profundizar en Linux y Bash Scripting con aplicaciones y ejemplos reales: