Entrada y salida: read, echo, printf, here-doc

Introducción

Los scripts interactúan con el usuario y con otros programas a través de la entrada estándar, la salida estándar y la salida de error. Dominar read, echo, printf y los here-documents permite escribir scripts robustos y bien comunicados.

echo — Salida estándar


echo "Hola mundo"
echo "Valor de HOME: $HOME"

# -n: no añadir salto de línea al final
echo -n "Introduce tu nombre: "

# -e: interpretar secuencias de escape
echo -e "Línea 1\nLínea 2\tcon tabulador"
echo -e "\033[31mTexto en rojo\033[0m"     # color ANSI

# Redirigir a stderr (para mensajes de error)
echo "Error: fichero no encontrado" >&2
          

Nota: el comportamiento de echo varía entre shells y sistemas. Para salida formateada fiable, usar printf.

printf — Salida formateada

printf es más portable y potente que echo. Su sintaxis es similar a la del printf de C.


printf "Hola %s\n" "mundo"
printf "Nombre: %-15s Edad: %3d\n" "Juan" 30
printf "Nombre: %-15s Edad: %3d\n" "María" 25
# Salida alineada:
# Nombre: Juan            Edad:  30
# Nombre: María           Edad:  25

printf "%.2f\n" 3.14159    # 3.14
printf "%05d\n" 42         # 00042 (relleno con ceros)
printf "%x\n" 255          # ff (hexadecimal)

# Guardar en variable en lugar de imprimir
printf -v FECHA "%(%Y-%m-%d)T" -1    # fecha actual
          

Especificadores de formato:

  • %s → cadena
  • %d → entero decimal
  • %f → punto flotante
  • %x → hexadecimal
  • %o → octal
  • \n → salto de línea
  • \t → tabulador
  • %-Ns → alineado a la izquierda en N caracteres
  • %Nd → entero con N dígitos mínimos

read — Leer entrada del usuario


# Leer una línea en una variable
read NOMBRE
echo "Hola, $NOMBRE"

# Con prompt (-p)
read -p "Introduce tu nombre: " NOMBRE

# Ocultar la entrada (contraseñas, -s de silent)
read -sp "Contraseña: " PASSWORD
echo    # salto de línea tras la entrada oculta
echo "Contraseña recibida (longitud: {#PASSWORD})"

# Leer con timeout (-t)
if read -t 10 -p "Tienes 10 segundos para responder: " RESPUESTA; then
    echo "Respondiste: $RESPUESTA"
else
    echo "Tiempo agotado"
fi

# Leer en múltiples variables (divide por IFS, por defecto espacio/tab)
read -p "Introduce nombre y apellido: " NOMBRE APELLIDO
echo "Nombre: $NOMBRE, Apellido: $APELLIDO"

# Leer un solo carácter (-n)
read -n1 -p "¿Continuar? [s/n]: " RESP
echo
[[ "$RESP" =~ ^[sS]$ ]] && echo "Continuando..." || echo "Cancelado"
          

Leer fichero línea a línea:


# IFS= preserva los espacios iniciales y finales
# -r evita interpretar backslashes
while IFS= read -r linea; do
    echo "Procesando: $linea"
done < /etc/hosts
          

Here-document (here-doc)

Un here-doc permite pasar un bloque de texto multilínea a un comando, como si fuera un fichero. Es muy útil para generar ficheros de configuración, enviar correos o pasar SQL a una base de datos.

Sintaxis básica:


cat <<EOF
Esta es la primera línea.
El valor de HOME es: $HOME
Hoy es: $(date +%F)
EOF
          

Sin expansión de variables (heredoc literal):


# Entrecomillar el delimitador para evitar expansiones
cat <<'EOF'
Esto es literal: $HOME no se expande
Y tampoco $(date)
EOF
          

Con indentación (heredoc con guión):


# El - permite indentar el contenido con tabuladores
cat <<-EOF
	Esta línea tiene un tabulador al principio
	que será eliminado en la salida
	EOF
          

Generar un fichero de configuración:


#!/usr/bin/env bash
SERVIDOR="web01"
PUERTO=8080

cat > /etc/mi_app.conf <<EOF
# Configuración generada automáticamente el $(date)
servidor=$SERVIDOR
puerto=$PUERTO
log=/var/log/mi_app.log
EOF

echo "Configuración generada en /etc/mi_app.conf"
          

Here-string (cadena simple):


# Pasar una cadena como stdin sin pipe
grep "root" <<< "root:x:0:0:root:/root:/bin/bash"

# Útil para evitar el pipe en casos simples
read PRIMERO SEGUNDO <<< "hola mundo"
echo "$PRIMERO"   # hola
echo "$SEGUNDO"   # mundo
          

Usar printf en lugar de echo para salida formateada portable. Usar siempre IFS= read -r para leer ficheros línea a línea sin perder espacios ni interpretar backslashes.

Manejo de errores: exit codes, set -euo pipefail, trap, depuración

Índice de la sección

Índice del curso