detomas.net Curso de Bash desde cero
Descargar PDF

Curso de Bash desde cero / Capítulo 8

Scripting

Definición

Un script es un archivo de texto que contiene comandos que la shell ejecutará secuencialmente para permitir así automatizar tareas repetitivas.

Convenciones en Bash

  1. Extensión .sh. Es opcional (a Bash le da igual), pero ayuda a saber de un vistazo qué es cada archivo.

  2. Primera línea #!/bin/bash, el llamado shebang. Le dice al sistema con qué intérprete tiene que ejecutar el archivo. Sin él, el sistema usa la shell que le parezca, y tu script puede comportarse distinto.

  3. Permisos de ejecución con chmod +x script.sh.

Hay dos formas de lanzar un script:

./script.sh        # necesita el permiso de ejecución
bash script.sh     # funciona aunque no lo tenga

Consejo

Verás también #!/usr/bin/env bash como shebang. Es más portable: en vez de dar por hecho que Bash está en /bin/bash, lo busca en el PATH. En Linux los dos funcionan; si tus scripts van a correr también en macOS, mejor la segunda.

Cuando algo no funciona

Antes de volverte loco mirando el código, Bash trae sus propias herramientas:

bash -x script.sh       # muestra cada línea ya expandida antes de ejecutarla
bash -n script.sh       # solo comprueba la sintaxis, sin ejecutar nada

También puedes activar el modo detallado desde dentro del script, poniendo set -x en la línea a partir de la cual quieres ver el detalle.

Consejo

Y una recomendación que te ahorrará horas: instala ShellCheck, que revisa scripts y te avisa de los fallos típicos (comillas que faltan, variables mal escritas, comparaciones dudosas).

sudo apt install shellcheck
shellcheck script.sh

Ejemplo básico

#!/bin/bash

# Mi primer script
echo "Hola, este es mi primer script en Bash"
date
echo "Tu directorio actual es: $(pwd)"

Variables

name="Nica"
echo "Hola $name"

Aritmética básica

Bash trata todo como texto por defecto. Para que haga cuentas hay que pedírselo con $(( )):

a=5
b=3

suma=$((a + b))
echo "La suma es $suma"           # La suma es 8
echo "El doble de a es $((a * 2))"

Dentro de $(( )) no hace falta el $ delante de las variables: $((a + b)) funciona igual que $(($a + $b)).

Aviso

Sin $(( )) no hay cuenta que valga:

suma=a+b
echo "$suma"      # a+b   <- texto literal, no 8

Verás también let suma=a+b, que es la forma antigua. Hace lo mismo, pero usa $(( )): es lo estándar en Bash moderno y se lee mejor.

Lectura de datos

read pide datos al usuario mientras el script se ejecuta.

#!/bin/bash

read -r -p "¿Cuál es tu nombre? " nombre
echo "Hola, $nombre"

read -r -p "¿Cuál es tu edad? " edad
echo "Tu edad es $edad"

read -r -s -p "Contraseña: " clave
echo
echo "Has escrito ${#clave} caracteres"
Opción Qué hace
-p Muestra el texto de la pregunta en la misma línea
-s Oculta lo que se escribe (para contraseñas)
-r No interpreta las barras invertidas como escape

Consejo

Usa siempre read -r. Sin la -r, si el usuario escribe una ruta de Windows como C:\Users\nica, Bash se come las barras y guarda C:Usersnica. Es un fallo silencioso y molesto de encontrar.

No hay ningún caso práctico en el que quieras read sin -r.

Argumentos y parámetros

Los scripts pueden recibir argumentos desde la línea de comandos.

#!/bin/bash
echo "El nombre del script es: $0"
echo "El primer parámetro es: $1"
echo "El segundo parámetro es: $2"
echo "Número de parámetros: $#"
echo "Todos los argumentos: $@"

Ejecución con argumentos: ./script.sh argumento1 argumento2

Variable Qué contiene
$0 El nombre del script (./script.sh)
$1, $2, $3 El primer, segundo, tercer argumento…
$# Cuántos argumentos se han pasado
"$@" Todos los argumentos, cada uno por separado
$* Todos los argumentos, pero pegados en una sola cadena

Aviso

Entre "$@" y $* hay una diferencia que importa cuando algún argumento lleva espacios. Con "$@" cada argumento se mantiene entero; con $* se juntan todos y luego se parten por los espacios.

Usa siempre "$@", con comillas. Es lo correcto en el 99% de los casos, y por el mismo motivo que se explica en el capítulo de comillas.

Un patrón que conviene coger desde el principio: comprobar que te han pasado lo que esperabas antes de seguir.

#!/bin/bash

if [ $# -lt 2 ]; then
    echo "Uso: $0 <origen> <destino>" >&2
    exit 1
fi

origen="$1"
destino="$2"
echo "Copiando de $origen a $destino"

Nota

Tienes el script completo un poco más arriba, en este mismo apartado.

Ejercicios

  1. Crea un script que imprima en pantalla: Hola mundo desde Bash.

  2. Crea un script que muestre la fecha y el directorio actual.

  3. Crea un script que guarde tu nombre en una variable y lo muestre en pantalla.

  4. Crea un script que declare dos variables numéricas, las sume, reste y multiplique, mostrando el resultado de cada operación.

  5. Crea un script que pida tu nombre con read y lo muestre.

  6. Crea un script que pida dos números al usuario y muestre su suma.

  7. Crea un script con tres argumentos que muestre el primero y el tercero.

  8. Crea un script con argumentos que muestre el número total.

  9. Crea un script que reciba dos números como argumentos y muestre su suma, resta, multiplicación y división.

  10. Crea un script que cree un archivo de texto y guarde tu nombre en su interior.

Posibles correcciones (ten en cuenta que pueden variar dependiendo de tu sistema operativo y directorios existentes)

  1. Crea un script que imprima en pantalla: Hola mundo desde Bash.
#!/bin/bash

# Nombre: hola_mundo.sh

# Descripción: Script que imprime "Hola mundo desde Bash"
echo "Hola mundo desde Bash"
Crear y ejecutar el script:

# Crear el archivo
nano hola_mundo.sh

# Copiar el contenido del script anterior

# Guardar: Ctrl + O, Enter, Ctrl + X

# Dar permisos de ejecución
chmod +x hola_mundo.sh

# Ejecutar el script
./hola_mundo.sh

# O ejecutar sin permisos de ejecución
bash hola_mundo.sh
  1. Crea un script que muestre la fecha y el directorio actual.
#!/bin/bash

# Nombre: fecha_directorio.sh

# Descripción: Muestra la fecha actual y el directorio de trabajo
echo "=== Información del Sistema ==="
echo "Fecha y hora actual:"
date
echo ""
echo "Directorio actual:"
pwd

# Alternativa con formato más personalizado
    echo ""
    echo "=== Información Detallada ==="
    echo "Fecha: $(date '+%d/%m/%Y')"
    echo "Hora: $(date '+%H:%M:%S')"
    echo "Directorio: $(pwd)"
    Crear y ejecutar el script:
    nano fecha_directorio.sh
    chmod +x fecha_directorio.sh
    ./fecha_directorio.sh
  1. Crea un script que guarde tu nombre en una variable y lo muestre en pantalla.
#!/bin/bash

# Nombre: mi_nombre.sh

# Descripción: Guarda un nombre en una variable y lo muestra

# Declarar la variable
nombre="Nica"

# Mostrar el contenido de la variable
echo "Mi nombre es: $nombre"

# Alternativa con más información
echo "Hola, mi nombre es ${nombre}"
echo "Bienvenido/a, ${nombre}!"

# También puedes usar comillas simples para texto literal
echo 'El nombre guardado es:' "$nombre"
Crear y ejecutar el script:
nano mi_nombre.sh
chmod +x mi_nombre.sh
./mi_nombre.sh
  1. Crea un script que declare dos variables numéricas, las sume, reste y multiplique, mostrando el resultado de cada operación.
#!/bin/bash

# Nombre: operaciones.sh

# Descripción: Realiza operaciones matemáticas básicas

# Declarar dos variables numéricas
num1=15
num2=5
echo "=== Operaciones Matemáticas ==="
echo "Primer número: $num1"
echo "Segundo número: $num2"
echo ""

# Suma
suma=$((num1 + num2))
echo "Suma: $num1 + $num2 = $suma"

# Resta
resta=$((num1 - num2))
echo "Resta: $num1 - $num2 = $resta"

# Multiplicación
# OJO: el nombre de la variable va SIN tilde. Bash solo admite letras
# sin acentos, números y guion bajo en los nombres de variable.
multiplicacion=$((num1 * num2))
echo "Multiplicación: $num1 * $num2 = $multiplicacion"

# Bonus: División y módulo
division=$((num1 / num2))
modulo=$((num1 % num2))
echo ""
echo "=== Operaciones adicionales ==="
echo "División: $num1 / $num2 = $division"
echo "Módulo: $num1 % $num2 = $modulo"
Crear y ejecutar el script:
nano operaciones.sh
chmod +x operaciones.sh
./operaciones.sh
  1. Crea un script que pida tu nombre con read y lo muestre.
#!/bin/bash

# Nombre: pedir_nombre.sh

# Descripción: Pide el nombre al usuario y lo muestra

# Pedir el nombre al usuario
echo "Por favor, introduce tu nombre:"
read nombre

# Mostrar el nombre
echo "Hola, $nombre! Bienvenido/a."

# Alternativa con prompt en la misma línea

# read -p "Introduce tu nombre: " nombre

# echo "Hola, $nombre!"

# Versión más completa
echo ""
echo "Encantado de conocerte, ${nombre}!"
Crear y ejecutar el script:
nano pedir_nombre.sh
chmod +x pedir_nombre.sh
./pedir_nombre.sh
  1. Crea un script que pida dos números al usuario y muestre su suma.
#!/bin/bash

# Nombre: suma_numeros.sh

# Descripción: Pide dos números al usuario y muestra su suma

# Pedir el primer número
echo "Introduce el primer número:"
read num1

# Pedir el segundo número
echo "Introduce el segundo número:"
read num2

# Calcular la suma
suma=$((num1 + num2))

# Mostrar el resultado
    echo ""
    echo "La suma de $num1 + $num2 = $suma"

    # Alternativa con read -p (prompt en la misma línea)

    # read -p "Introduce el primer número: " num1

    # read -p "Introduce el segundo número: " num2

    # suma=$((num1 + num2))

    # echo "La suma es: $suma"
    Crear y ejecutar el script:
    nano suma_numeros.sh
    chmod +x suma_numeros.sh
    ./suma_numeros.sh
  1. Crea un script con tres argumentos que muestre el primero y el tercero.
#!/bin/bash

# Nombre: argumentos_1_3.sh

# Descripción: Muestra el primer y tercer argumento

# Verificar que se pasaron al menos 3 argumentos
if [ $# -lt 3 ]; then
    echo "Error: Se necesitan 3 argumentos"
    echo "Uso: $0 argumento1 argumento2 argumento3"
    exit 1
fi

# Mostrar el primer y tercer argumento
echo "El primer argumento es: $1"
echo "El tercer argumento es: $3"

# Información adicional
echo ""
echo "=== Información adicional ==="
echo "El segundo argumento (no mostrado) es: $2"
echo "Total de argumentos recibidos: $#"
Crear y ejecutar el script
nano argumentos_1_3.sh
chmod +x argumentos_1_3.sh
./argumentos_1_3.sh primero segundo tercero

# Ejemplo con diferentes valores
./argumentos_1_3.sh Hola Mundo Bash
  1. Crea un script con argumentos que muestre el número total.
#!/bin/bash

# Nombre: contar_argumentos.sh

# Descripción: Muestra el número total de argumentos recibidos

# Mostrar el número total de argumentos
echo "Número total de argumentos: $#"

# Información adicional
if [ $# -eq 0 ]; then
    echo "No se recibieron argumentos"
elif [ $# -eq 1 ]; then
    echo "Se recibió 1 argumento: $1"
else
    echo "Se recibieron $# argumentos"
    echo "Todos los argumentos: $@"
fi

# Listar cada argumento
echo ""
echo "=== Lista de argumentos ==="
contador=1
for arg in "$@"; do
    echo "Argumento $contador: $arg"
    ((contador++))
done
Crear y ejecutar el script:
nano contar_argumentos.sh
chmod +x contar_argumentos.sh

# Probar con diferentes cantidades de argumentos
./contar_argumentos.sh
./contar_argumentos.sh uno
./contar_argumentos.sh uno dos tres
./contar_argumentos.sh Hola Mundo desde Bash
  1. Crea un script que reciba dos números como argumentos y muestre su suma, resta, multiplicación y división.
#!/bin/bash

# Nombre: calculadora.sh

# Descripción: Realiza operaciones matemáticas con dos números como
argumentos

# Verificar que se recibieron 2 argumentos
if [ $# -ne 2 ]; then
    echo "Error: Se necesitan exactamente 2 números"
    echo "Uso: $0 numero1 numero2"
    exit 1
fi

# Guardar los argumentos en variables
num1=$1
num2=$2
echo "=== CALCULADORA ==="
echo "Primer número: $num1"
echo "Segundo número: $num2"
echo ""

# Realizar las operaciones
suma=$((num1 + num2))
resta=$((num1 - num2))
multiplicacion=$((num1 * num2))
echo "Suma: $num1 + $num2 = $suma"
echo "Resta: $num1 - $num2 = $resta"
echo "Multiplicación: $num1 * $num2 = $multiplicacion"

# División (con verificación de división por cero)
if [ $num2 -eq 0 ]; then
    echo "División: No se puede dividir por cero"
else
    division=$((num1 / num2))
    modulo=$((num1 % num2))
    echo "División: $num1 / $num2 = $division"
    echo "Módulo: $num1 % $num2 = $modulo"
fi

Crear y ejecutar el script:

nano calculadora.sh
chmod +x calculadora.sh

# Probar con diferentes números
./calculadora.sh 20 5
./calculadora.sh 100 7
./calculadora.sh 15 0
  1. Crea un script que cree un archivo de texto y guarde tu nombre en su interior.
#!/bin/bash

# Nombre: crear_archivo_nombre.sh

# Descripción: Crea un archivo de texto y guarda un nombre en

# Definir el nombre del archivo
archivo="mi_nombre.txt"

# Definir el nombre a guardar
nombre="Nica"

# Crear el archivo y guardar el nombre
echo "$nombre" > "$archivo"

# Confirmar que se creó
echo "Archivo '$archivo' creado exitosamente"
echo "Contenido guardado: $nombre"

# Mostrar el contenido del archivo
echo ""
echo "=== Contenido del archivo ==="
cat "$archivo"

# Bonus: Añadir más información al archivo
echo "" >> "$archivo"
echo "Fecha de creación: $(date)" >> "$archivo"
echo "Directorio: $(pwd)" >> "$archivo"
echo ""
echo "=== Contenido completo del archivo ==="
cat "$archivo"
Crear y ejecutar el script:
nano crear_archivo_nombre.sh
chmod +x crear_archivo_nombre.sh
./crear_archivo_nombre.sh

# Verificar que se creó el archivo
ls -l mi_nombre.txt
cat mi_nombre.txt

Versión alternativa con input del usuario:

#!/bin/bash

# Nombre: crear_archivo_nombre_input.sh

# Descripción: Pide el nombre al usuario y lo guarda en un archivo

# Pedir el nombre al usuario
read -p "Introduce tu nombre: " nombre

# Definir el nombre del archivo
archivo="nombre_usuario.txt"

# Crear el archivo y guardar el nombre
echo "$nombre" > "$archivo"
echo "Tu nombre ha sido guardado en '$archivo'"
echo "Contenido: $(cat $archivo)"