Tracks
/
Bash
Bash
/
Temario
/
Here documents
He

Here documents en Bash

{one: "1 ejercicio", many: "%{count} ejercicios", other: "%{count} ejercicios"}

Acerca de Here documents

En los scripts de Bash, un «here document» (o «heredoc») redirige varias líneas de entrada a un comando o programa, como si las escribieras directamente en el terminal. Es una herramienta muy potente para incrustar texto de varias líneas dentro de tus scripts sin necesidad de archivos externos ni de complejas manipulaciones de strings.

Características y sintaxis principales

  1. Delimitador: un heredoc empieza con el operador << seguido de una palabra delimitadora (a la que a menudo se llama «marcador» o «terminador»). Este delimitador puede ser cualquier palabra que elijas, pero lo habitual es usar algo como EOF, END o TEXT para mayor claridad. Para que el código sea más legible, puedes usar como delimitador algo descriptivo, por ejemplo END_INSTALLATION_INSTRUCTIONS.

  2. Contenido: después del << DELIMITER inicial, escribes el contenido que quieres redirigir. Puede ser varias líneas de texto, código o cualquier otra cosa.

  3. Finalización: el heredoc termina cuando la palabra delimitadora vuelve a aparecer sola en una línea, sin espacios en blanco delante ni detrás.

Sintaxis básica

command << DELIMITER
  Content line 1
  Content line 2
  ...
  Content line N
DELIMITER

Cómo funciona

  • Bash lee todas las líneas entre el << DELIMITER inicial y el DELIMITER final.
  • Bash conecta este contenido a la entrada estándar del comando.
  • El comando procesa esta entrada como si viniera del teclado.

Ejemplo 1: salida de texto simple

cat << EOF
This is the first line.
This is the second line.
This is the third line.
EOF

Salida:

This is the first line.
This is the second line.
This is the third line.

En este ejemplo:

  • cat es el comando.
  • << EOF inicia el heredoc con EOF como delimitador.
  • Las tres líneas de texto son el contenido.
  • EOF sola en su propia línea pone fin al heredoc.
  • Después, cat muestra el contenido que ha recibido.

Ejemplo 2: usarlo con wc (recuento de palabras)

wc -l << END
Line 1
Line 2
Line 3
END

Salida:

3

Aquí, wc -l cuenta el número de líneas. El heredoc proporciona las tres líneas como entrada.

Ejemplo 3: pasar datos a un script

El script:

#!/usr/bin/env bash

# Script to process input
while IFS= read -r line; do
  echo "Processing: $line"
done

Llama al script desde un prompt interactivo de Bash usando un heredoc:

./your_script << MY_DATA
Item 1
Item 2
Item 3
MY_DATA

Salida:

Processing: Item 1
Processing: Item 2
Processing: Item 3

Variaciones y características avanzadas

Contenido literal

Bash realiza expansión de variables, sustitución de comandos y expansión aritmética dentro de un heredoc. En este sentido, los heredocs se comportan como strings entre comillas dobles.

cat << EOF
The value of HOME is $HOME
The current date is $(date)
Two plus two is $((2 + 2))
EOF

Salida:

The value of HOME is /home/glennj
The current date is Thu Apr 24 13:47:32 EDT 2025
Two plus two is 4

Cuando el delimitador va entre comillas (simples o dobles), estas expansiones no se producen. El contenido se toma de forma literal. Esto es como los strings entre comillas simples.

cat << 'EOF'
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
EOF

Salida:

The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))

Eliminar las tabulaciones iniciales

Si usas <<- (con un guion al final) en lugar de <<, Bash eliminará los caracteres de tabulación iniciales de cada línea del heredoc. Esto resulta útil para indentar el contenido del heredoc dentro de tu script sin afectar a la salida.

# Note, the leading whitespace is tab characters only, not spaces!
# The ending delimiter can have leading tabs as well.
cat <<- END
	This line has 1 leading tab.
	  This line has a leading tab and some spaces.
		This line 2 leading tabs.
	END

La salida se imprime con todas las tabulaciones iniciales eliminadas:

This line has 1 leading tab.
    This line has a leading tab and some spaces.
This line 2 leading tabs.
Caution

El autor no recomienda este uso. Aunque puede mejorar la legibilidad del script,

  1. es fácil reemplazar los caracteres de tabulación por espacios sin querer (tu editor puede hacerlo automáticamente), y
  2. es difícil distinguir a simple vista la diferencia entre espacios y tabulaciones.

Cuándo usar here documents

  • Entrada de varias líneas: cuando necesitas proporcionar varias líneas de texto a un comando.
  • Archivos de configuración: incrustar pequeños fragmentos de configuración dentro de un script.
  • Generación de código: crear código sobre la marcha dentro de un script.
  • Interacciones con scripts: simular la entrada del usuario para programas interactivos.
  • Evitar archivos externos: cuando quieres evitar crear archivos temporales.

Un uso típico podría ser proporcionar un texto de ayuda:

#!/usr/bin/env bash

usage() {
    cat << END_USAGE
Refresh database tables.

usage: ${0##*/} [-h|--help] [-A|--no-archive]

where: --no-archive flag will _skip_ the archive jobs
END_USAGE
}

# ... parsing command line options here ...

if [[ $flag_help == "true" ]]; then
  usage
  exit 0
fi

Posibles inconvenientes

  • Los documentos incrustados grandes pueden hacer que tu código sea más difícil de leer. Puede ser mejor distribuir tu script con la documentación en archivos separados.
  • Los here documents pueden romper el flujo del código. Puede que estés en una sección de código muy anidada cuando quieres pasar algo de texto a un programa. La indentación del heredoc puede resultar chocante en comparación con el código que la rodea.

Here strings

Al igual que los here documents, los here strings (o «herestrings») proporcionan entrada a un comando. Sin embargo, mientras que los heredocs se dan como un bloque de texto, los herestrings se dan como un único string de texto. Los here strings usan la sintaxis <<< "text".

tr 'a-z' 'A-Z' <<< "upper case this string"

Salida:

UPPER CASE THIS STRING

A diferencia de los heredocs, no se necesita un delimitador final.

¿Por qué usar here strings?

Se puede usar una tubería en lugar de un here string:

echo "upper case this string" | tr 'a-z' 'A-Z'

Entonces, ¿por qué usar un here string?

Piensa en el caso en que obtienes el string como salida de un cálculo largo, y quieres pasar el resultado a dos comandos distintos. Si usas tuberías, tienes que ejecutar el cálculo dos veces:

some_long_running_calculation | first_command
some_long_running_calculation | second_command

Un enfoque más eficiente es capturar la salida del cálculo (usando sustitución de comandos) y usar here strings para proporcionar entrada a los dos comandos siguientes:

result=$( some_long_running_calculation )
first_command <<< "$result"
second_command <<< "$result"

Aquí tienes una aplicación real de ese ejemplo:

  • capturar la respuesta JSON de una consulta a una API REST (que está paginada),
  • proporcionar los datos JSON a un programa jq para analizar los resultados y volcarlos en un archivo, y después
  • proporcionar los datos JSON a otro programa jq para determinar la URL de la siguiente consulta.
# initialize the output CSV file
echo "ID,VALUE" > data.csv

url='https//example.com/api/query?page=1'

while true; do
  json=$( curl "$url" )

  # convert the results part of the response into CSV
  jq -r '.results[] | [.id, .value] | @csv' <<< "$json"

  # get the URL for the next page
  url=$( jq -r '.next_url // ""' <<< "$json" )
  if [[ "$url" == "" ]]; then
    break
  fi
done >> data.csv

Fíjate en la posición de la redirección de la salida. Toda la salida del bucle while se añadirá al archivo data.csv.

Heredocs y herestrings como redirección

Como no son más que formas de redirección, se pueden combinar con otras operaciones de redirección:

cat <<< END_OF_TEXT > output.txt
This is my important text.
END_OF_TEXT

awk '...' <<< "$my_var" >> result.csv

En resumen

Los here documents (o «heredocs») son una forma flexible y cómoda de gestionar la entrada de varias líneas en los scripts de Bash. Simplifican el proceso de incrustar texto y datos directamente en tus scripts, lo que los hace más autónomos y fáciles de leer.

Los here strings (o «herestrings») son como los here documents, pero ofrecen una sintaxis más sencilla y dinámica.

Editar en GitHub El enlace se abre en una nueva ventana o pestaña