Skip to main content

Command Palette

Search for a command to run...

Agregar colores a los scripts de Bash

Guía completa para una terminal más expresiva

Published
10 min read
Agregar colores a los scripts de Bash

Cualquiera que haya trabajado con pipelines de CI/CD o scripts de automatización sabe lo frustrante que es leer un muro de texto blanco sobre negro tratando de encontrar dónde algo salió mal. Esto me llevó a explorar a fondo la coloración de salida en Bash, y lo que encontré fue sorprendentemente simple y poderoso.

En esta entrada vamos a cubrir todo lo que necesitas saber para darle vida a tus scripts con color: desde los fundamentos de los códigos ANSI hasta patrones avanzados que puedes reutilizar en tus proyectos.


¿Por qué colorear la salida de tus scripts?

Antes de entrar en el código, vale la pena reflexionar sobre por qué esto importa. Cuando ejecutas un script que despliega infraestructura, corre pruebas o gestiona contenedores, la cantidad de output puede ser abrumadora. Los colores te permiten:

  • Identificar errores al instante: rojo para fallos, verde para éxito.

  • Separar secciones lógicas: cada fase de tu pipeline puede tener su propio color.

  • Mejorar la experiencia del usuario: si otros desarrolladores usan tus scripts, agradecerán la claridad visual.

  • Reducir el tiempo de depuración: encontrar el problema en un log colorizado es exponencialmente más rápido.

En el contexto de DevOps, donde la automatización es el pan de cada día, esto no es un lujo — es productividad real.


Los códigos de escape ANSI: la base de todo

La magia detrás de los colores en la terminal son los códigos de escape ANSI. El estándar ANSI (American National Standards Institute) define una serie de secuencias de caracteres que las terminales interpretan como instrucciones de formato en lugar de texto visible.

La estructura básica de una secuencia de escape es:

\e[CODIGOm

Donde:

  • \e (o \033 en octal, o \x1b en hexadecimal) inicia la secuencia de escape.

  • [ abre la secuencia CSI (Control Sequence Introducer).

  • CODIGO es el número que define el color o estilo.

  • m cierra la secuencia.

Tabla de colores de primer plano (texto)

Color

Código de primer plano

Código de fondo

Negro

30

40

Rojo

31

41

Verde

32

42

Amarillo

33

43

Azul

34

44

Magenta

35

45

Cian

36

46

Gris claro

37

47

Gris oscuro

90

100

Rojo claro

91

101

Verde claro

92

102

Amarillo claro

93

103

Azul claro

94

104

Magenta claro

95

105

Cian claro

96

106

Blanco

97

107

Códigos de estilo (no relacionados con color)

Código

Descripción

0

Restablecer/Normal

1

Texto en negrita

2

Texto tenue

3

Texto en cursiva

4

Texto subrayado

5

Texto parpadeante

7

Invertir colores

8

Texto oculto

9

Texto tachado


Tu primer texto en color

El comando echo imprime texto en la terminal. Para que interprete las secuencias de escape ANSI, necesitamos la opción -e:

echo -e "\e[31mTexto en rojo\e[0m"

Desglosemos esto:

  • \e[31m → Activa el color rojo (código 31 de primer plano).

  • Texto en rojo → El contenido que se mostrará en rojo.

  • \e[0m → Restablece el formato a la normalidad (código 0).

⚠️ Importante: El \e[0m al final es crucial. Sin él, todo el texto que imprimas después en esa sesión de terminal aparecerá en rojo. Siempre cierra tus secuencias de color.


Usando variables para mayor legibilidad

Escribir \e[31m cada vez que quieres rojo no es práctico ni legible. La solución es almacenar los códigos en variables:

RED="\e[31m"
GREEN="\e[32m"
YELLOW="\e[33m"
BLUE="\e[34m"
MAGENTA="\e[35m"
CYAN="\e[36m"
ENDCOLOR="\e[0m"

echo -e "\({RED}Error: algo salió mal\){ENDCOLOR}"
echo -e "\({GREEN}Éxito: despliegue completado\){ENDCOLOR}"
echo -e "\({YELLOW}Advertencia: revisa la configuración\){ENDCOLOR}"

Ahora el código es mucho más expresivo. Cualquiera que lo lea entiende inmediatamente la intención.

Script básico completo

#! /usr/bin/env bash

RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"

echo -e "\({RED}This is some red text, \){ENDCOLOR}"
echo -e "\({GREEN}And this is some green text\){ENDCOLOR}"

Combinando estilos y colores

Aquí es donde la cosa se pone interesante. Puedes combinar múltiples códigos separándolos con punto y coma (;) dentro de una sola secuencia de escape:

\e[ESTILO;COLORm

Por ejemplo:

#! /usr/bin/env bash

RED="31"
GREEN="32"
BOLDGREEN="\e[1;${GREEN}m"
ITALICRED="\e[3;${RED}m"
ENDCOLOR="\e[0m"

echo -e "\({BOLDGREEN}Behold! Bold, green text.\){ENDCOLOR}"
echo -e "\({ITALICRED}Italian italics\){ENDCOLOR}"

Observa cómo separamos el código de estilo del código de color: 1;32 significa "negrita + verde". Puedes incluso combinar tres o más códigos: \e[1;4;31m te daría texto rojo, negrita y subrayado.

Más combinaciones útiles

BOLD="\e[1m"
DIM="\e[2m"
UNDERLINE="\e[4m"
BLINK="\e[5m"
REVERSE="\e[7m"
STRIKETHROUGH="\e[9m"

BOLD_RED="\e[1;31m"
UNDERLINE_BLUE="\e[4;34m"
BOLD_YELLOW_ON_RED="\e[1;33;41m"  # Texto amarillo negrita sobre fondo rojo

Color de fondo

Los códigos de fondo (40-47 y 100-107) se usan de la misma forma. Puedes combinarlos con colores de texto:

# Texto blanco sobre fondo rojo (ideal para errores críticos)
echo -e "\e[97;41m CRITICAL ERROR \e[0m Something broke badly"

# Texto negro sobre fondo amarillo (ideal para advertencias)
echo -e "\e[30;43m WARNING \e[0m Check your configuration"

# Texto negro sobre fondo verde (ideal para éxito)
echo -e "\e[30;42m SUCCESS \e[0m Deployment completed"

Este patrón de "badges" o etiquetas de color es muy común en herramientas CLI profesionales.


Colores de 256 colores y RGB (True Color)

Las terminales modernas soportan más que los 16 colores básicos ANSI.

256 colores

Puedes acceder a una paleta de 256 colores usando:

# Primer plano: \e[38;5;COLORm
# Fondo:        \e[48;5;COLORm

echo -e "\e[38;5;208mTexto naranja (color 208)\e[0m"
echo -e "\e[48;5;27mFondo azul intenso\e[0m"

Los valores van de 0 a 255, donde 0-7 son los colores estándar, 8-15 son los colores brillantes, 16-231 es un cubo de color 6×6×6, y 232-255 son tonos de gris.

True Color (24-bit RGB)

Si tu terminal lo soporta (la mayoría de las modernas lo hacen), puedes usar colores RGB exactos:

# Primer plano: \e[38;2;R;G;Bm
# Fondo:        \e[48;2;R;G;Bm

echo -e "\e[38;2;255;100;0mNaranja personalizado\e[0m"
echo -e "\e[38;2;0;200;255mAzul cielo\e[0m"

Esto te da acceso a más de 16 millones de colores.


Alternativas a \e: compatibilidad entre terminales

Aunque \e funciona en la mayoría de las terminales modernas, existen alternativas más portables:

Secuencia

Descripción

\e

Funciona en la mayoría de terminales modernas

\033

Notación octal, más portable

\x1b

Notación hexadecimal

$'\e'

Sintaxis ANSI-C quoting de Bash

Si necesitas máxima compatibilidad, usa \033:

RED="\033[31m"
ENDCOLOR="\033[0m"
echo -e "\({RED}Compatible con más terminales\){ENDCOLOR}"

O usa el comando tput, que consulta la base de datos terminfo de tu sistema:

RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
BOLD=$(tput bold)
RESET=$(tput sgr0)

echo "\({RED}Rojo con tput\){RESET}"
echo "\({BOLD}\){GREEN}Verde negrita${RESET}"

La ventaja de tput es que genera la secuencia correcta para cada terminal automáticamente.


Patrón práctico: funciones de logging con color

En lugar de usar variables sueltas, un patrón más profesional es crear funciones de logging reutilizables:

#! /usr/bin/env bash

# --- Colores ---
RED="\e[31m"
GREEN="\e[32m"
YELLOW="\e[33m"
BLUE="\e[34m"
BOLD="\e[1m"
DIM="\e[2m"
ENDCOLOR="\e[0m"

# --- Funciones de logging ---
log_info() {
    echo -e "\({BLUE}[INFO]\){ENDCOLOR} $1"
}

log_success() {
    echo -e "\({GREEN}[OK]\){ENDCOLOR} $1"
}

log_warning() {
    echo -e "\({YELLOW}[WARN]\){ENDCOLOR} $1"
}

log_error() {
    echo -e "\({RED}[ERROR]\){ENDCOLOR} $1"
}

log_step() {
    echo -e "\({BOLD}\){BLUE}==>\({ENDCOLOR}\){BOLD} \(1\){ENDCOLOR}"
}

# --- Uso ---
log_step "Iniciando despliegue..."
log_info "Conectando al cluster de Kubernetes..."
log_success "Conexión establecida"
log_warning "La imagen no tiene tag específico, usando :latest"
log_error "Fallo al aplicar el manifiesto: timeout después de 30s"

Este patrón es extremadamente útil para scripts de CI/CD, hooks de Git y herramientas de automatización.


Detectando soporte de color

No todas las terminales soportan colores (piensa en logs redirigidos a archivos o terminales mínimas). Es buena práctica verificar:

#! /usr/bin/env bash

# Desactivar colores si no estamos en una terminal interactiva
if [[ -t 1 ]]; then
    RED="\e[31m"
    GREEN="\e[32m"
    YELLOW="\e[33m"
    ENDCOLOR="\e[0m"
else
    RED=""
    GREEN=""
    YELLOW=""
    ENDCOLOR=""
fi

echo -e "\({GREEN}Esto se ve verde en terminal, y normal en un archivo\){ENDCOLOR}"

El test -t 1 verifica si el file descriptor 1 (stdout) está conectado a una terminal. Si el output se redirige a un archivo (script.sh > log.txt), los códigos de color se omiten, evitando ensuciar los logs con caracteres de escape ilegibles.

También puedes respetar la variable de entorno NO_COLOR (estándar de la comunidad: no-color.org):

if [[ -n "${NO_COLOR:-}" ]]; then
    RED=""
    GREEN=""
    ENDCOLOR=""
fi

Ejemplo completo: script de despliegue con salida colorizada

Para cerrar, aquí tienes un ejemplo más realista que podrías adaptar para tus propios scripts de despliegue o hooks de Git:

#! /usr/bin/env bash
set -euo pipefail

# ============================================================
# Colores y estilos
# ============================================================
if [[ -t 1 ]]; then
    RED="\e[31m"
    GREEN="\e[32m"
    YELLOW="\e[33m"
    BLUE="\e[34m"
    CYAN="\e[36m"
    BOLD="\e[1m"
    DIM="\e[2m"
    NC="\e[0m"  # No Color
else
    RED="" GREEN="" YELLOW="" BLUE="" CYAN="" BOLD="" DIM="" NC=""
fi

# ============================================================
# Funciones de utilidad
# ============================================================
header() {
    echo ""
    echo -e "\({BOLD}\){CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "\({BOLD}\){CYAN}  \(1\){NC}"
    echo -e "\({BOLD}\){CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

info()    { echo -e "  \({BLUE}ℹ\){NC}  $1"; }
success() { echo -e "  \({GREEN}✔\){NC}  $1"; }
warn()    { echo -e "  \({YELLOW}⚠\){NC}  $1"; }
error()   { echo -e "  \({RED}✘\){NC}  $1"; }
step()    { echo -e "  \({DIM}→\){NC}  $1"; }

# ============================================================
# Script principal
# ============================================================
header "DEPLOY v2.4.1 → production"

info "Verificando pre-requisitos..."
step "kubectl configurado: $(kubectl config current-context 2>/dev/null || echo 'N/A')"
step "Docker version: $(docker --version 2>/dev/null | cut -d' ' -f3 || echo 'N/A')"
success "Pre-requisitos verificados"

info "Construyendo imagen Docker..."
if docker build -t myapp:v2.4.1 . > /dev/null 2>&1; then
    success "Imagen construida exitosamente"
else
    error "Fallo al construir la imagen"
    exit 1
fi

info "Aplicando manifiestos de Kubernetes..."
warn "Usando namespace: production (¡cuidado!)"
success "Despliegue completado"

header "RESUMEN"
echo -e "  Estado:  \({GREEN}\){BOLD}EXITOSO${NC}"
echo -e "  Versión: \({CYAN}v2.4.1\){NC}"
echo -e "  Tiempo:  \({DIM}12.4s\){NC}"
echo ""

Consejos finales

  1. Siempre resetea con \e[0m al final de cada línea coloreada. No hacerlo es la fuente número uno de bugs visuales.

  2. Usa funciones, no variables sueltas en scripts de producción. Son más mantenibles y puedes agregar timestamps, redirección a archivo, y otras mejoras en un solo lugar.

  3. Respeta NO_COLOR y -t 1. Tus scripts serán ciudadanos de primera clase en pipelines automatizados.

  4. No abuses del color. Si todo es colorido, nada destaca. Usa rojo solo para errores reales, amarillo para advertencias, y verde para confirmaciones de éxito.

  5. printf vs echo -e: Si buscas portabilidad máxima, printf maneja secuencias de escape sin necesidad de flags adicionales:

    printf "\({RED}Error: %s\){ENDCOLOR}\n" "algo falló"
    
  6. Prueba en múltiples terminales. Lo que se ve perfecto en tu iTerm2 o Alacritty puede verse diferente en una terminal más básica.

Las combinaciones son infinitas y son tuyas. Ahora que tienes las herramientas, dale personalidad a tus scripts y haz que la terminal sea un lugar más amigable para trabajar.

109 views
Agregar colores a los scripts de Bash