← Automatización con Scripts en Bash Bloque 1 · Del comando al script · Tema 1 de 42

Tema 1

Por qué automatizar con Bash

Todas las mañanas, los mismos seis comandos. Todos los viernes, la misma copia de seguridad. En cada versión, los mismos pasos para subirla al servidor. Cada repetición cuesta minutos y abre una oportunidad de equivocarse. Este tema explica qué significa automatizar, qué tareas lo merecen, por qué Bash es casi siempre el primer lenguaje para hacerlo y en qué casos conviene elegir otro.

1. Una tarea hecha a mano

Ana mantiene una pequeña aplicación web. La aplicación escribe un archivo de registro por día en ~/app/logs, y si nadie los atiende terminan llenando el disco. Así que cada mañana, antes de empezar a trabajar, Ana abre una terminal y hace esto:

terminal · la rutina de cada mañana
$ cd ~/app/logs
$ ls
app-2026-09-13.log.gz  app-2026-10-12.log.gz  app-2026-10-13.log  app-2026-10-14.log
$ gzip app-2026-10-13.log                # comprimir el registro de ayer
$ find . -name '*.log.gz' -mtime +30     # ¿hay alguno de hace más de un mes?
./app-2026-09-13.log.gz
$ rm ./app-2026-09-13.log.gz
$ df -h .                              # ¿cuánto espacio queda?
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        40G   23G   15G  61% /

Son comandos que ya conoces del curso anterior, y la tarea lleva unos tres minutos. Nada de esto es difícil. El problema está en otra parte:

Los cuatro problemas tienen la misma solución: escribir los pasos una vez, en un archivo, y dejar que la computadora los ejecute.

2. Qué es un script

Un script de shell es un archivo de texto que contiene comandos, los mismos que se escribirían en la terminal, y que la shell ejecuta de principio a fin como si alguien los tecleara uno tras otro. A eso se suman variables, condiciones, bucles y funciones, que lo convierten en un programa.

La versión más simple de un script es una lista de comandos guardada en un archivo. La rutina de Ana podría empezar así:

limpiar-registros.sh · primera versión
#!/usr/bin/env bash
# Comprime el registro de ayer y borra los de hace más de 30 días.
cd ~/app/logs
gzip "app-$(date -d yesterday +%F).log"
find . -name '*.log.gz' -mtime +30 -delete
df -h .

Comparada con la sesión manual, ya cambiaron dos cosas. El nombre del archivo de ayer no se lee en pantalla: lo calcula date. Y la búsqueda de archivos viejos borra directamente con -delete, porque ya no hay una persona mirando la lista. Que el script deba arreglárselas sin alguien que mire es la diferencia más profunda entre trabajar en la consola y automatizar, y gran parte de este curso trata de sus consecuencias.

terminal
$ chmod +x limpiar-registros.sh
$ ./limpiar-registros.sh
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        40G   23G   15G  61% /

Tres minutos de tecleo se convirtieron en un solo comando. Y un comando se puede programar para que se ejecute solo, todos los días a las 3:30 de la mañana, con una línea en la tabla de cron:

crontab
30 3 * * *  /home/ana/bin/limpiar-registros.sh

El último bloque del curso de Terminal ya mostró cómo crear un archivo así y darle permiso de ejecución, y el tema 2 lo retoma con detalle. Por ahora importa la idea: un script es la tarea escrita, y lo escrito se puede repetir, revisar, compartir y programar.

Esta primera versión tiene fallas

Si el directorio no existe, cd falla, pero el script sigue adelante y ejecuta los comandos siguientes en otro lugar. Si ayer no hubo registro, gzip muestra un error que nadie lee. Y no hay forma de indicarle otro directorio. Volveremos a este script en la sección 11, ya corregido, y cada tema del curso agrega una de las piezas que le faltan.

3. Qué tareas conviene automatizar

No todo merece un script. Escribirlo, probarlo y mantenerlo cuesta tiempo, y ese costo debe pagarse con lo que ahorra. Estas son las señales de que una tarea es buena candidata:

SeñalPor qué cuentaEjemplo
Se repiteEl costo de escribir el script se paga una vez; el ahorro, en cada repetición.Limpiar registros cada día, generar un informe cada semana.
Tiene muchos pasosCuantos más pasos, más fácil es saltarse uno o hacerlos en otro orden.Compilar, ejecutar las pruebas, empaquetar y copiar al servidor.
Un error es caroUn script hace siempre lo mismo; una persona cansada, no.Desplegar en producción, borrar datos viejos.
Debe ocurrir en un momento fijoLas personas olvidan; cron, no.Copias de seguridad cada noche, a las 2:00.
Se aplica a muchos elementosLo que con uno es un comando, con mil es imposible a mano.Renombrar 800 fotos, convertir 200 documentos.
Otras personas deben poder hacerlaEl script es una instrucción que no se puede malinterpretar.Preparar el entorno de desarrollo de alguien que llega al equipo.
Hay que esperar y vigilarComprobar algo cada cinco minutos es trabajo para una máquina.Avisar si el disco pasa del 90 % o si un sitio deja de responder.

Y estas son señales de que, al menos por ahora, conviene seguir haciéndolo a mano:

La regla de las tres veces

Una pauta práctica: la primera vez, hazlo a mano. La segunda, hazlo a mano y anota los pasos. La tercera, convierte esas notas en un script. Para entonces ya conoces la tarea, sus variantes y lo que puede fallar.

4. Hacer las cuentas

La decisión de automatizar se puede razonar con números aproximados. Basta multiplicar cuánto dura la tarea por las veces que se hará en, digamos, un año, y compararlo con lo que llevaría escribir el script.

TareaDuraciónFrecuenciaTiempo al año
Limpiar registros3 minutosCada día hábil (unos 220)11 horas
Copia de seguridad de un proyecto10 minutosCada semana8,7 horas
Desplegar una versión25 minutosDos veces por semana43 horas
Preparar el equipo de alguien nuevo3 horasCuatro veces al año12 horas

El script de limpieza se escribe y se prueba en una hora; el de despliegue, quizá en una tarde. En ambos casos el ahorro es grande. Pero la cuenta subestima el beneficio, porque solo mide minutos. Un despliegue manual que falla una vez al año por un paso olvidado puede costar más que todo el tiempo de la tabla.

La cuenta también sirve en sentido contrario. Pasar dos días perfeccionando un script para algo que se hace una vez al año y lleva diez minutos es un mal negocio, aunque resulte entretenido. La excepción son las tareas raras pero delicadas, como restaurar una copia de seguridad: se hacen poco, pero cuando hacen falta no hay margen para improvisar.

5. Más que tiempo

El ahorro de tiempo es el argumento más visible, pero rara vez el más importante. Una tarea automatizada gana otras cualidades:

CualidadQué significa
ConsistenciaSe hace igual cada vez, sin importar quién la ejecute, a qué hora ni con cuánto apuro.
DocumentaciónEl script describe con exactitud cómo se hace la tarea. A diferencia de un documento aparte, no puede quedar desactualizado sin que se note: si deja de ser cierto, deja de funcionar.
DelegaciónCualquiera puede ejecutarlo, incluso quien no conoce los detalles. Y una máquina puede ejecutarlo sin nadie.
RevisiónSe puede leer antes de ejecutarlo, pedir a un colega que lo revise y guardarlo en un control de versiones para saber qué cambió y cuándo.
RegistroPuede anotar qué hizo, cuándo y con qué resultado. Una tarea manual no deja rastro.
EscalaLo que funciona con un servidor o con diez archivos funciona igual con cien.

Hay un último beneficio, más sutil: escribir el script obliga a entender la tarea. Para que una máquina la haga hay que contestar preguntas que a mano se resuelven sin pensar. ¿Qué pasa si el directorio no existe? ¿Y si hoy no hubo registro? ¿Y si el disco está lleno? Responderlas mejora el procedimiento aunque nunca se llegue a automatizar.

6. Por qué Bash

Cualquier lenguaje de programación puede automatizar tareas. Bash no es el más elegante ni el más rápido, y tiene rarezas que este curso no va a disimular. Aun así, para automatizar tareas de un sistema es casi siempre la primera opción, por cinco razones:

RazónEn concreto
Ya está instaladoViene en prácticamente todas las distribuciones de Linux, en los servidores, en los contenedores y en los sistemas de integración continua. Un script de Bash funciona en la máquina de destino sin instalar nada.
Ya lo sabesEs el mismo lenguaje que usas en la consola. Todo comando que escribiste en la terminal funciona sin cambios dentro de un script, y viceversa: puedes probar cada línea antes de guardarla.
Ejecutar programas es lo más fácilEn otros lenguajes, ejecutar un programa externo y conectar su salida con otro requiere una biblioteca y varias líneas. En Bash es la operación básica: se escribe el comando, y | lo conecta con el siguiente.
Trabaja con archivos y procesosRedirecciones, permisos, comodines, señales y códigos de salida forman parte del lenguaje, no de una biblioteca.
Es estableUn script escrito hace quince años sigue funcionando. Bash cambia muy despacio y cuida la compatibilidad.

La segunda razón merece subrayarse. La mayor parte de lo que necesitas para automatizar ya lo aprendiste en el curso de Terminal: los comandos, las redirecciones, las tuberías, grep, sed y awk. Lo que agrega este curso es lo que hace falta para que esos comandos funcionen solos: guardar datos en variables, tomar decisiones, repetir, organizar el código y reaccionar ante los errores.

7. Un lenguaje para unir programas

Bash se describe a menudo como un lenguaje pegamento. Su fuerza no está en lo que hace por sí mismo, que es poco, sino en coordinar programas que ya existen y que hacen muy bien una sola cosa. Un script de Bash rara vez comprime, compila o copia por red: le pide a gzip, a gcc o a rsync que lo hagan, y se ocupa de decidir cuándo, con qué datos y qué hacer si algo sale mal.

Un disparador, que puede ser una persona o cron, ejecuta un script; el script decide, repite y maneja errores, y pone en marcha programas especializados: gcc y make para compilar, tar y gzip para empaquetar, rsync y ssh para copiar y desplegar, grep y awk para analizar texto; todos se apoyan en el sistema operativo Disparador tú, cron u otro script script.sh decide repite maneja errores gcc · make — compilar tar · gzip — empaquetar rsync · ssh — desplegar grep · awk — analizar Sistema operativo: procesos, archivos, permisos y red
El script no hace el trabajo pesado: coordina a los programas que lo hacen. Esa división es la que vuelve a Bash tan eficaz para automatizar, y tan incómodo para todo lo demás.

Para ver la diferencia, piensa en esta tarea: «empaqueta el directorio del proyecto con la fecha en el nombre y cópialo al servidor de respaldos». En Bash son dos líneas, porque cada paso es un programa que ya existe:

respaldo.sh
archivo="proyecto-$(date +%F).tar.gz"
tar -czf "$archivo" ~/proyecto && scp "$archivo" respaldos@servidor:/copias/

En un lenguaje de propósito general la misma tarea requiere una biblioteca para comprimir, otra para la conexión segura, y el manejo de sus errores. Se puede hacer, y a veces es lo correcto, pero no es lo más directo. En Bash, lo más directo es justamente esto.

8. Lo que Bash hace mal

La otra cara del pegamento es que Bash es un lenguaje pobre para casi todo lo que no sea coordinar comandos. Conviene conocer sus límites desde el principio, para no forzarlo donde no rinde.

DebilidadQué ocurreDónde se trata
Todo es textoNo hay números con decimales, ni estructuras anidadas, ni objetos. Una lista dentro de otra lista no se puede representar de forma natural.Temas 7 y 8
Los espacios y las comillasUna variable sin comillas se parte en palabras. Es la fuente más común de errores en scripts de Bash.Temas 3 y 5
Los errores pasan en silencioPor defecto, si un comando falla, el script continúa con el siguiente como si nada.Bloque 6
RendimientoCada comando externo es un proceso nuevo. Un bucle que llama a un programa diez mil veces es lento.Temas 16 y 32
Sintaxis irregular[ ], [[ ]], (( )) y $( ) se parecen y no hacen lo mismo. Un espacio de más o de menos cambia el significado.Bloques 2 y 3
Pocas herramientas de pruebaExisten, pero no hay la cultura de pruebas automáticas que tienen otros lenguajes. Los scripts grandes se vuelven difíciles de cambiar con confianza.Tema 26

Tres ejemplos breves dan una idea de cómo se manifiestan. El primero, la aritmética: Bash solo calcula con enteros.

terminal
$ echo $(( 7 / 2 ))
3
$ echo $(( 1.5 + 2 ))
bash: 1.5 + 2 : syntax error: invalid arithmetic operator (error token is ".5 + 2 ")

El segundo, los espacios. Una variable que contiene un nombre de archivo con un espacio se parte en dos si no se la pone entre comillas:

terminal
$ archivo="informe final.txt"
$ touch "$archivo"
$ ls -l $archivo                       # sin comillas: dos argumentos
ls: cannot access 'informe': No such file or directory
ls: cannot access 'final.txt': No such file or directory
$ ls -l "$archivo"                     # con comillas: uno
-rw-r--r-- 1 ana ana 0 oct 14 09:12 informe final.txt

El tercero es el más peligroso: un comando falla y el script sigue adelante.

limpiar-temporales.sh · no lo ejecutes
#!/usr/bin/env bash
cd /var/tmp/compilacion
rm -rf ./*
Por qué este script es peligroso

Si /var/tmp/compilacion no existe, cd falla y muestra un error, pero el directorio actual no cambia. La línea siguiente borra entonces todo lo que haya en el directorio desde el que se ejecutó el script, que puede ser tu directorio personal. La corrección mínima es cd /var/tmp/compilacion || exit 1: si el cambio de directorio falla, el script termina. En el tema 23 veremos cómo hacer que todo el script se detenga ante el primer error.

Ninguno de estos problemas es motivo para evitar Bash. Son motivo para aprenderlo bien: casi todos tienen una solución conocida, y este curso las presenta una por una. Pero sí son motivo para reconocer cuándo una tarea ha dejado de ser adecuada para Bash.

9. Cuándo elegir otra herramienta

Bash es la herramienta correcta cuando la tarea consiste sobre todo en ejecutar programas, mover archivos y conectar resultados. Cuando consiste sobre todo en procesar datos, calcular o modelar algo complejo, conviene otra. Esta tabla resume las alternativas más comunes:

Si la tarea es…ConvienePor qué
Encadenar comandos, mover y comprimir archivos, programar tareasBashEs para lo que fue hecho.
Procesar datos estructurados, como JSON o CSV con comillas y campos anidadosPython, o jq para una consulta puntualTienen lectores de esos formatos. Con sed se puede, hasta que un dato trae una coma o un salto de línea.
Cálculos con decimales, estadísticas, fechas complejasPython, o awk si es algo breveBash no tiene decimales ni tipos de datos.
Compilar un proyecto rehaciendo solo lo que cambiómake, o la herramienta de compilación del lenguajeSaben qué depende de qué. Un script de Bash puede llamarlas, como en el tema 36.
Dejar decenas de servidores con la misma configuraciónAnsible u otra herramienta de gestión de configuraciónDescriben el estado deseado y lo aplican en paralelo, sin repetir lo que ya está hecho.
Compilar, probar y desplegar en cada cambio del repositorioUn sistema de integración continuaOrganiza y registra las ejecuciones. Pero cada paso suele ser, en el fondo, un comando de shell.
Una aplicación con interfaz, o con rendimiento críticoUn lenguaje de propósito generalBash no está pensado para eso.

En la práctica, las herramientas conviven. Un sistema de integración continua ejecuta un script de Bash, que llama a make para compilar y a un pequeño programa en Python para generar un informe. Elegir no es casarse con un lenguaje: es usar cada uno donde rinde.

Hay señales claras de que un script ha crecido más de la cuenta y conviene reescribirlo en otro lenguaje:

10. Bash y sh: una nota sobre portabilidad

Como viste en el primer tema del curso de Terminal, Bash desciende de la shell de Bourne, sh. El lenguaje de sh está fijado por un estándar, POSIX, que respetan todas las shells de la familia. Bash cumple ese estándar y le agrega muchas comodidades: [[ ]], los arrays, la aritmética con (( )), las expresiones regulares con =~ y otras.

De ahí surge una decisión que todo script toma en su primera línea:

Primera líneaQué prometeVentajaCosto
#!/bin/shQue el script usa solo lo que define POSIX.Funciona en cualquier sistema tipo Unix, incluso en los mínimos que no traen Bash.Renunciar a las comodidades de Bash.
#!/usr/bin/env bashQue el script necesita Bash.Se puede usar todo el lenguaje.Requiere que Bash esté instalado en el destino.

Este curso escribe scripts de Bash, con la segunda línea, porque Bash está en casi cualquier sistema Linux y sus agregados hacen los scripts más seguros y legibles. El error que conviene evitar es otro: escribir un script con características de Bash y encabezarlo con #!/bin/sh. En Debian y Ubuntu, /bin/sh no es Bash sino dash, que no las entiende, y el script falla de formas desconcertantes. El tema 2 explica cómo funciona esa primera línea.

11. Un primer vistazo a un script real

Volvamos al script de Ana. Esta es la versión que podrías escribir al terminar el bloque 6. No hace falta entenderla ahora: está aquí para mostrar hacia dónde va el curso, y para que reconozcas, línea por línea, de qué tema sale cada pieza.

limpiar-registros.sh · versión final
#!/usr/bin/env bash
# limpiar-registros.sh — comprime los registros anteriores a hoy
# y borra los comprimidos de más de N días.
# Uso: limpiar-registros.sh [directorio] [días]
set -euo pipefail

dir="${1:-$HOME/app/logs}"
dias="${2:-30}"
hoy="$(date +%F)"

if [[ ! -d "$dir" ]]; then
  echo "Error: no existe el directorio $dir" >&2
  exit 1
fi

comprimidos=0
for archivo in "$dir"/*.log; do
  [[ -e "$archivo" ]] || continue             # no hay ningún .log
  [[ "$archivo" == *"$hoy"* ]] && continue     # el de hoy sigue en uso
  gzip "$archivo"
  comprimidos=$(( comprimidos + 1 ))
done

borrados=$(find "$dir" -name '*.log.gz' -mtime +"$dias" -print -delete | wc -l)
echo "Comprimidos: $comprimidos · Borrados: $borrados"
PiezaQué haceTema
#!/usr/bin/env bashIndica qué programa debe interpretar el archivo.2
Los comentarios con #Explican qué hace el script y cómo se usa.4
set -euo pipefailDetiene el script ante el primer error, en lugar de seguir a ciegas.23
"${1:-$HOME/app/logs}"Toma el primer argumento o, si no se dio, un valor por defecto.6 y 20
"$(date +%F)"Guarda en una variable la salida de un comando.5
if [[ ! -d "$dir" ]]Comprueba que el directorio exista antes de tocar nada.11
>&2 y exit 1Escribe el error donde corresponde y termina indicando que falló.10 y 25
for … in "$dir"/*.logRecorre los archivos de registro uno por uno.14
continueSalta un archivo y pasa al siguiente.17
$(( comprimidos + 1 ))Lleva la cuenta de los archivos procesados.7
find … -delete | wc -lBorra los archivos viejos y cuenta cuántos fueron.32

Comparada con la primera versión de la sección 2, esta hace lo mismo, pero se comporta de otra manera cuando algo no es como se esperaba:

terminal
$ limpiar-registros.sh                        # con los valores por defecto
Comprimidos: 1 · Borrados: 1
$ limpiar-registros.sh /srv/web/logs 15       # otro directorio, otro plazo
Comprimidos: 6 · Borrados: 4
$ limpiar-registros.sh /no/existe
Error: no existe el directorio /no/existe
$ echo $?                                     # el código de salida informa del fallo
1

Y, programado con cron, registra en un archivo lo que hizo cada noche, de modo que se pueda revisar después. Los detalles de esa línea son el tema 34:

crontab
30 3 * * *  /home/ana/bin/limpiar-registros.sh >> /home/ana/limpieza.log 2>&1

12. Las cualidades de un buen script

La diferencia entre la primera versión y la última no está en lo que hacen cuando todo va bien, sino en lo que hacen cuando algo va mal. Un script que se ejecuta solo, sin nadie mirando, tiene que cumplir exigencias que un comando escrito a mano no necesita. Estas son las que guían todo el curso:

CualidadQué significaDónde se aprende
LegibleOtra persona, o tú dentro de seis meses, puede entender qué hace y por qué.Tema 4
ParametrizableLos datos que cambian, como directorios, plazos o servidores, se pasan como argumentos en lugar de estar escritos dentro.Bloque 5
PrudenteComprueba lo que necesita antes de actuar, y se detiene ante el primer error en lugar de seguir a ciegas.Bloques 3 y 6
HonestoTermina con código 0 si salió bien y con otro si falló, para que quien lo llame, sea una persona, cron u otro script, pueda saberlo.Tema 10
Silencioso en el éxito, claro en el errorNo llena la pantalla de mensajes inútiles, pero cuando algo falla dice qué y dónde, por la salida de errores.Tema 25
LimpioNo deja archivos temporales ni procesos sueltos, aunque lo interrumpan a la mitad.Tema 24
RepetibleEjecutarlo dos veces seguidas no causa daño ni duplica nada. Se dice que es idempotente.Tema 27

Ningún script necesita todas estas cualidades desde la primera línea. Un script de cinco líneas para uso propio puede prescindir de casi todas. Pero cuanto más importante es la tarea, y cuanto menos supervisión tiene, más de ellas hacen falta.

13. Automatizar con cuidado

La automatización amplifica: hace lo correcto más rápido y más veces, pero también hace lo incorrecto más rápido y más veces. Un error que a mano afecta a un archivo, en un bucle afecta a todos. Algunas precauciones que retomaremos a lo largo del curso:

  1. Prueba primero a mano. Ejecuta cada comando en la terminal antes de guardarlo en el script, y comprueba que hace lo que esperas.
  2. Prueba sin consecuencias. Cambia el rm o el gzip por un echo que solo muestre qué se haría. Cuando la lista es la correcta, quita el echo. Muchos scripts ofrecen esto como una opción, a menudo llamada --dry-run.
  3. Prueba en un lugar seguro. Un directorio de prueba con archivos de mentira, o una máquina virtual, nunca los datos reales en la primera ejecución.
  4. Comprueba antes de borrar. Que el directorio existe, que la variable no está vacía, que estás en la máquina correcta. Un rm -rf "$dir/"* con dir vacía se convierte en rm -rf /*.
  5. No escribas contraseñas dentro del script. Los scripts se copian, se comparten y se guardan en repositorios. Las credenciales van en archivos aparte, con permisos restringidos, o en variables de entorno.
  6. Deja rastro. Un script que se ejecuta solo debe anotar qué hizo. Si un día algo falla, el registro es lo único que tendrás para averiguar qué pasó.
  7. Revisa que siga funcionando. Una tarea automatizada que falla en silencio es peor que una manual: nadie se entera hasta que es tarde. El tema 40 trata de cómo recibir un aviso cuando algo no anda.
Una herramienta que conviene instalar desde ya

ShellCheck es un programa que lee un script y señala errores comunes: variables sin comillas, comparaciones mal escritas, comandos que pueden fallar sin que se note. Detecta la mayoría de los problemas de la sección 8 antes de ejecutar nada. En Debian y Ubuntu se instala con sudo apt install shellcheck. Lo usaremos a partir del tema 4.

14. El mapa del curso

Los 42 temas están ordenados para que cada bloque agregue a tus scripts una capacidad nueva. Cada uno responde una pregunta:

BloqueTemasLa pregunta que responde
1. Del comando al script1–4¿Qué es un script, cómo se ejecuta y cómo lee Bash cada línea?
2. Variables y datos5–9¿Cómo guardo, transformo y pido datos?
3. Códigos de salida y condicionales10–13¿Cómo sé si algo salió bien, y cómo decido qué hacer?
4. Bucles14–17¿Cómo repito una acción sobre muchos elementos?
5. Funciones y argumentos18–22¿Cómo organizo el código y recibo datos desde afuera?
6. Manejo de errores y scripts robustos23–27¿Cómo hago que el script falle de forma segura?
7. Texto y expresiones regulares28–32¿Cómo extraigo, valido y genero información?
8. Tareas programadas33–35¿Cómo hago que se ejecute solo, a la hora indicada?
9. Automatización en la práctica36–40¿Cómo automatizo compilaciones, respaldos, despliegues y alertas?
10. Integración y cierre41–42¿Cómo uso todo junto en una herramienta completa?

Los bloques 2 a 5 enseñan el lenguaje; el 6 es el que separa un script que funciona de uno en el que se puede confiar; del 7 al 9 se aplica todo a tareas reales. En el tema 2 escribimos, ejecutamos e instalamos el primer script.

15. Resumen

16. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué es un script de shell?

Un archivo de texto con comandos que la shell ejecuta de principio a fin, como si alguien los tecleara en orden. Con variables, condiciones, bucles y funciones se convierte en un programa.

2. ¿Cuál es la diferencia más importante entre ejecutar comandos a mano y ejecutarlos desde un script?

A mano, una persona mira la salida de cada comando y decide qué hacer a continuación. Un script tiene que arreglárselas solo: debe prever qué puede fallar y qué hacer en cada caso, porque nadie está mirando.

3. Menciona cuatro señales de que una tarea conviene automatizarla.

Se repite con frecuencia; tiene muchos pasos; un error es caro; debe ocurrir en un momento fijo; se aplica a muchos elementos; otras personas deben poder hacerla; requiere vigilar algo de forma periódica. Cualquiera cuatro de ellas.

4. ¿Por qué no conviene automatizar una tarea que todavía no se entiende bien?

Porque el script reproduciría la confusión, solo que más rápido y más veces. Conviene hacerla a mano algunas veces, conocer sus variantes y lo que puede fallar, y después escribir el script.

5. Una tarea lleva 5 minutos y se hace cada día hábil. ¿Cuánto tiempo ocupa en un año, aproximadamente?

Con unos 220 días hábiles, son 1100 minutos: algo más de 18 horas al año.

6. ¿Qué beneficios aporta un script además del ahorro de tiempo?

Consistencia, porque se hace igual cada vez; documentación exacta del procedimiento; la posibilidad de delegarlo en otra persona o en una máquina; que se pueda revisar y versionar; que deje registro de lo que hizo; y que escale a muchos elementos.

7. ¿Qué significa que Bash sea un lenguaje «pegamento»?

Que su fuerza está en coordinar programas existentes: ejecutarlos, conectar sus salidas y decidir qué hacer según su resultado. El trabajo pesado, como comprimir, compilar o copiar por red, lo hacen esos programas.

8. ¿Qué muestra echo $(( 7 / 2 )), y por qué?

Muestra 3. La aritmética de Bash solo trabaja con enteros, y la división descarta la parte decimal.

9. ¿Qué puede pasar si en un script se ejecuta cd /un/directorio seguido de rm -rf ./*, y el directorio no existe?

El cd falla, pero el script continúa, y el rm borra el contenido del directorio desde el que se ejecutó el script. Se evita con cd /un/directorio || exit 1, o con el modo estricto del tema 23.

10. Un script tiene que leer un archivo JSON con datos anidados y calcular promedios con decimales. ¿Es Bash la mejor opción?

No. Bash no tiene estructuras anidadas ni decimales. Conviene Python, o al menos jq para el JSON. Si el resto de la tarea consiste en ejecutar comandos, el script de Bash puede llamar a ese programa.

11. ¿Por qué un script que usa [[ ]] puede fallar si empieza con #!/bin/sh?

Porque [[ ]] es una extensión de Bash, no parte del estándar POSIX. En sistemas donde /bin/sh es otra shell, como dash en Debian y Ubuntu, esa sintaxis no se reconoce.

12. ¿Qué significa que un script sea «honesto» con su código de salida?

Que termina con código 0 cuando todo salió bien y con un código distinto de 0 cuando algo falló. Así, quien lo ejecuta, sea una persona, cron u otro script, puede saber el resultado sin leer los mensajes.

13. ¿Qué quiere decir que un script sea idempotente?

Que ejecutarlo varias veces seguidas deja el sistema en el mismo estado que ejecutarlo una vez: no duplica datos ni causa daño por repetirse.

14. ¿Cómo se puede probar un script que borra archivos sin correr el riesgo de borrar los equivocados?

Reemplazando el comando que borra por un echo que muestre qué se borraría, y revisando esa lista. También ejecutándolo primero en un directorio de prueba o en una máquina virtual.

Para practicar

  1. Haz una lista de cinco tareas que repites en tu computadora o en tu trabajo. Para cada una, anota cuánto dura, cada cuánto la haces y cuántas de las señales de la sección 3 cumple.
  2. Elige la tarea de la lista con más tiempo al año y escribe, en un archivo de texto, los comandos exactos con que la harías en la terminal. Es el borrador de tu primer script.
  3. Para esos mismos pasos, anota qué podría salir mal en cada uno: un archivo que no existe, un disco lleno, una conexión caída. Esas notas son las comprobaciones que el script necesitará.
  4. Ejecuta echo $(( 10 / 3 )) y echo "10 / 3" | bc -l. Compara los resultados.
  5. Crea un archivo con un espacio en el nombre y prueba a listarlo con una variable, con y sin comillas, como en la sección 8.
  6. Averigua qué es /bin/sh en tu sistema con ls -l /bin/sh. ¿Es un enlace a Bash, a dash o a otra shell?
  7. Instala ShellCheck y comprueba que funciona con shellcheck --version.