Características y Mejoras de Bash 5.1
Lanzado en diciembre de 2020, Bash 5.1 introdujo varias características y mejoras notables para la programación moderna de scripts de shell.
Nuevas Variables de Shell
EPOCHSECONDS y EPOCHREALTIME
Dos nuevas variables especiales para acceder a la hora actual:
# Obtener timestamp Unix actual en segundos
echo "Timestamp actual: ${EPOCHSECONDS}"
# Obtener timestamp Unix actual con precisión de microsegundos
echo "Timestamp de alta precisión: ${EPOCHREALTIME}"
# Ejemplo práctico: Benchmarking simple
inicio="${EPOCHREALTIME}"
# ... alguna operación ...
sleep 0.5
fin="${EPOCHREALTIME}"
duracion=$(awk "BEGIN {print ${fin} - ${inicio}}")
echo "La operación tomó ${duracion} segundos"
# Ejemplo: Registro con timestamps precisos
log_message() {
printf '[%s.%06d] %s\n' \
"$(date -d "@${EPOCHSECONDS}" '+%Y-%m-%d %H:%M:%S')" \
"${EPOCHREALTIME#*.}" \
"$*"
}
log_message "Iniciando proceso"
Casos de uso:
- Medición precisa de rendimiento
- Timestamps de alta resolución para registro
- Evitar llamadas externas al comando
date - Temporización con precisión de microsegundos en scripts
Variable SRANDOM
Números aleatorios criptográficamente seguros:
# Generar número aleatorio seguro (si está disponible)
if [[ -n "${SRANDOM}" ]]; then
aleatorio_seguro="${SRANDOM}"
echo "Aleatorio seguro: ${aleatorio_seguro}"
else
echo "SRANDOM no disponible (requiere getrandom/getentropy)"
fi
# Ejemplo práctico: Generar archivo temporal con nombre aleatorio seguro
archivo_temp="/tmp/seguro_${SRANDOM}_${EPOCHSECONDS}.tmp"
Nota: SRANDOM requiere soporte del sistema para las llamadas getrandom() o getentropy().
Sintaxis de Redirección Mejorada
Redirección {varname}
Asignar descriptor de archivo a variable para mejor gestión de manejadores:
# Abrir descriptor de archivo y almacenarlo en variable
exec {fd}< entrada.txt
while IFS= read -r -u "${fd}" linea; do
echo "Leído: ${linea}"
done
exec {fd}<&- # Cerrar el descriptor de archivo
# Ejemplo práctico: Múltiples manejadores de archivos
exec {fd_entrada}< datos.txt
exec {fd_salida}> resultados.txt
exec {fd_error}> errores.txt
procesar_datos() {
while IFS= read -r -u "${fd_entrada}" linea; do
if validar_linea "${linea}"; then
echo "Procesado: ${linea}" >&"${fd_salida}"
else
echo "Error: ${linea}" >&"${fd_error}"
fi
done
}
procesar_datos
exec {fd_entrada}<&-
exec {fd_salida}>&-
exec {fd_error}>&-
Beneficios:
- Descriptores de archivo con nombre en lugar de números mágicos
- Asignación automática de FD evita conflictos
- Código más legible y mantenible
- Seguimiento más fácil de manejadores de archivos abiertos
Mejoras en Arreglos
Manejo Mejorado de Arreglos Asociativos
Mejor soporte para operaciones complejas con arreglos:
# Declarar arreglo asociativo con typeset
declare -A config=(
[host]="localhost"
[port]="8080"
[debug]="true"
)
# Expansión mejorada de arreglos
for key in "${!config[@]}"; do
printf '%s=%s\n' "${key}" "${config[${key}]}"
done
# Ejemplo práctico: Analizador de configuración
parsear_config() {
declare -gA app_config
local linea key value
while IFS='=' read -r key value; do
[[ "${key}" =~ ^[[:space:]]*# ]] && continue # Saltar comentarios
[[ -z "${key}" ]] && continue # Saltar líneas vacías
# Recortar espacios en blanco
key="${key#"${key%%[![:space:]]*}"}"
key="${key%"${key##*[![:space:]]}"}"
value="${value#"${value%%[![:space:]]*}"}"
value="${value%"${value##*[![:space:]]}"}"
app_config["${key}"]="${value}"
done < config.ini
}
Soporte para Arreglos Multidimensionales
Manejo mejorado de estructuras de arreglos anidados.
Integración con Readline 8.1
Interacción mejorada de edición de texto y línea de comandos:
Enlaces de Teclas e Historial
# Configurar readline en ~/.inputrc
# Habilitar finalización sin distinción de mayúsculas/minúsculas
set completion-ignore-case on
# Habilitar estadísticas visibles para finalizaciones
set visible-stats on
# Mostrar todas las finalizaciones inmediatamente
set show-all-if-ambiguous on
# Usar colores para el prefijo de finalización
set colored-completion-prefix on
Búsqueda Mejorada en el Historial
# En tu script o .bashrc
# Vincular Ctrl+R para búsqueda incremental inversa (predeterminado, mejorado en 5.1)
bind '"\C-r": reverse-search-history'
# Vincular Ctrl+S para búsqueda incremental hacia adelante
bind '"\C-s": forward-search-history'
# Manejo mejorado del historial
shopt -s histappend # Añadir al historial
shopt -s cmdhist # Comandos multilínea como una entrada
HISTCONTROL=ignoreboth # Ignorar duplicados y espacios iniciales
HISTSIZE=10000
HISTFILESIZE=20000
Mejoras en el Manejo de Señales
Mejor propagación de señales en subprocesos y sustituciones de procesos:
# Manejo mejorado de traps en subprocesos
limpiar() {
echo "Limpiando..." >&2
rm -f "${archivo_temp}"
exit 130 # 128 + SIGINT
}
trap limpiar SIGINT SIGTERM
archivo_temp=$(mktemp)
# La señal se propaga correctamente a través de tuberías
tarea_larga | procesar_salida &
pid=$!
# Esperar trabajo en segundo plano con manejo adecuado de señales
wait "${pid}" 2>/dev/null
codigo_salida=$?
if [[ ${codigo_salida} -gt 128 ]]; then
senal=$((codigo_salida - 128))
echo "Proceso terminado por señal ${senal}" >&2
fi
Corrección de Errores y Casos Límite
Manejo de Subprocesos
Comportamiento mejorado al crear subprocesos:
# Herencia de variables de subproceso más confiable
variable_externa="padre"
(
# El subproceso ahora hereda las variables del padre de forma más confiable
echo "En subproceso: ${variable_externa}"
variable_interna="hijo"
)
# variable_externa sigue accesible, variable_interna no
echo "Después del subproceso: ${variable_externa}"
Casos Límite en Coincidencia de Patrones
Casos límite corregidos en coincidencia de patrones glob:
# Coincidencia glob más confiable con caracteres especiales
shopt -s nullglob # Expansión vacía para globs sin coincidencias
shopt -s extglob # Coincidencia de patrones extendida
# Ejemplo: Coincidir archivos pero manejar sin coincidencias elegantemente
archivos=(*.txt)
if [[ ${#archivos[@]} -eq 0 ]]; then
echo "No se encontraron archivos .txt"
else
printf 'Encontrados: %s\n' "${archivos[@]}"
fi
Mejoras de Rendimiento
- Expansión de variables más rápida en bucles
- Operaciones de arreglos optimizadas
- Uso reducido de memoria para arreglos grandes
- Eficiencia mejorada en coincidencia de patrones
Notas de Compatibilidad
Actualización desde Bash 5.0
La mayoría de los scripts son compatibles, pero tenga en cuenta:
EPOCHSECONDSyEPOCHREALTIMEson nuevos; verifique su existencia si se dirige a versiones anterioresSRANDOMpuede no estar disponible en todos los sistemas- Se corrigieron algunos casos límite oscuros en el comportamiento de expansión
Verificación de Versión
# Verificar versión de Bash antes de usar características 5.1
if [[ "${BASH_VERSINFO[0]}" -ge 5 ]] && [[ "${BASH_VERSINFO[1]}" -ge 1 ]]; then
# Seguro usar características de Bash 5.1
timestamp="${EPOCHSECONDS}"
else
# Reversión para versiones anteriores
timestamp=$(date +%s)
fi
Referencias
- Archivo NEWS de Bash - Notas de lanzamiento oficiales
- Lanzamiento GNU Bash 5.1 - Distribución fuente
- Página man de Bash:
man bash(sección sobre características específicas de versión)
Recursos Adicionales
Para patrones más amplios de desarrollo en Bash y mejores prácticas, consulte:
- ../bash-development/SKILL.md - Patrones básicos de desarrollo en Bash
- ../bash-portability/SKILL.md - Compatibilidad entre versiones