Appearance
Scripts Bash
Un script es un archivo de texto con comandos que el shell ejecuta en orden. Bash es uno de los intérpretes más comunes en Linux y resulta útil para automatizar tareas repetitivas.
Crear y ejecutar un script
Crea un archivo, por ejemplo saludo.sh:
bash
#!/usr/bin/env bash
printf 'Hola, Linux\n'La primera línea, llamada shebang, indica qué intérprete debe ejecutar el archivo. #!/usr/bin/env bash busca Bash en el entorno del usuario.
Hay dos formas habituales de ejecutarlo:
bash
bash saludo.shO bien, darle permiso de ejecución y ejecutarlo por su ruta:
bash
chmod u+x saludo.sh
./saludo.shEl prefijo ./ indica que el archivo está en el directorio actual. Si aparece «Permission denied», revisa los permisos con ls -l saludo.sh. No es necesario usar sudo para ejecutar un script normal creado por el usuario.
Variables y argumentos
Asigna valores sin espacios alrededor del signo =. Usa comillas dobles al expandir variables para conservar los espacios:
bash
nombre="Ana Pérez"
printf 'Hola, %s\n' "$nombre"Los argumentos se reciben como $1, $2, etc. Usa "$@" para recorrerlos preservando cada argumento por separado, y $# para consultar cuántos se recibieron:
bash
#!/usr/bin/env bash
printf 'Argumentos recibidos: %s\n' "$#"
for argumento in "$@"; do
printf '-> %s\n' "$argumento"
doneEjecuta el ejemplo con argumentos entre comillas cuando contengan espacios:
bash
./argumentos.sh "primer valor" segundoCondiciones y comprobaciones
if permite ejecutar comandos según una condición. [[ ... ]] es una expresión de Bash útil para comparar texto y comprobar rutas:
bash
#!/usr/bin/env bash
ruta="${1:-.}"
if [[ -d "$ruta" ]]; then
printf 'Es un directorio: %s\n' "$ruta"
elif [[ -f "$ruta" ]]; then
printf 'Es un archivo: %s\n' "$ruta"
else
printf 'No existe: %s\n' "$ruta" >&2
exit 1
fi${1:-.} usa el primer argumento si se proporcionó y . en caso contrario. exit 1 comunica que el script terminó con error; exit 0 indica éxito. Por convención, un estado distinto de cero señala un fallo.
También se puede comprobar directamente si un comando terminó correctamente:
bash
if grep -q "ERROR" aplicacion.log; then
printf 'Se encontraron errores\n'
else
printf 'No se encontraron errores\n'
fiBucles y funciones
Un bucle for puede recorrer archivos o una lista de valores:
bash
for archivo in ./*.log; do
[[ -e "$archivo" ]] || continue
printf 'Archivo: %s\n' "$archivo"
doneLa comprobación [[ -e "$archivo" ]] evita procesar literalmente el patrón *.log cuando no hay coincidencias.
Las funciones agrupan comandos reutilizables:
bash
saludar() {
local nombre="${1:-mundo}"
printf 'Hola, %s\n' "$nombre"
}
saludar "${1:-}"local limita la variable a la función. La función recibe sus argumentos igual que el script.
Comandos frecuentes en scripts
| Comando o construcción | Uso habitual |
|---|---|
printf | Imprimir texto con formato; suele ser más predecible que echo para scripts. |
read | Leer una línea desde la entrada estándar. |
test o [[ ... ]] | Comprobar condiciones y rutas. [[ ... ]] es propio de Bash. |
grep | Buscar líneas que coincidan con un patrón. |
find | Buscar archivos por nombre, tipo o ubicación. |
sed | Transformar texto línea a línea. |
awk | Procesar texto organizado en campos. |
cut | Extraer campos delimitados de cada línea. |
sort y uniq | Ordenar líneas y quitar duplicados consecutivos. |
wc | Contar líneas, palabras o bytes. |
date | Obtener o formatear fecha y hora. |
mkdir -p | Crear directorios, incluidos los intermedios que falten. |
basename y dirname | Obtener el nombre final o el directorio de una ruta. |
command -v | Comprobar si un comando está disponible. |
Ejemplo de tuberías para contar cuántas líneas contienen ERROR:
bash
grep -h "ERROR" ./*.log 2>/dev/null | wc -lLas tuberías (|) conectan la salida de un comando con la entrada del siguiente. Las redirecciones > y >> escriben o añaden salida a un archivo, mientras que 2> redirige los mensajes de error. > reemplaza el contenido del archivo de destino.
Ejemplo: buscar registros
Este script recibe un directorio opcional y busca archivos .log que contengan el texto indicado:
bash
#!/usr/bin/env bash
set -u
directorio="${1:-.}"
patron="${2:-ERROR}"
if [[ ! -d "$directorio" ]]; then
printf 'No es un directorio: %s\n' "$directorio" >&2
exit 1
fi
find "$directorio" -type f -name '*.log' \
-exec grep -nH -- "$patron" {} +Guárdalo como buscar-errores.sh, dale permiso con chmod u+x buscar-errores.sh y ejecútalo:
bash
./buscar-errores.sh ./logs "timeout"grep puede devolver un estado distinto de cero si no encuentra coincidencias; eso no siempre representa un error del script. Tenlo en cuenta si activas set -e o si usas su resultado en una tubería.
Recomendaciones
- Cita las expansiones de variables, por ejemplo
"$ruta", para evitar que espacios o caracteres especiales separen argumentos. - Valida los argumentos y las rutas antes de modificar archivos.
- Envía mensajes de error a
stderrcon>&2y devuelve estados de salida coherentes. - Usa rutas explícitas y evita ejecutar scripts con privilegios elevados si no es necesario.
set -euo pipefailpuede ayudar a detectar ciertos errores, pero tiene excepciones y no reemplaza el manejo explícito de fallos. Añade sus opciones entendiendo cómo afectan a condiciones, funciones y tuberías.- Ejecuta
shellcheck script.shsi ShellCheck está instalado: detecta errores frecuentes y sugiere mejoras.