Redirección Here Document en bash: perfecta para generar código adicional desde scripts

En ocasiones pasa desapercibida ya que no se suele mencionar demasiado en las guías de scripting o se hace una pasada muy superficial sobre las posibilidades que ofrece. Especialmente en los casos en los que hay que “volcar” código adicional desde scripts en bash hacia otros scripts o ficheros. Afortunadamente, gracias a las redirecciones Here Document/Here-script esta tarea se hace bastante más llevadera.

Redireccionando código sin utilizar Here Document

Vamos a ver un ejemplo muy sencillo de script en bash en el que generamos un HTML a base de “echo” y haciendo redirecciones al fichero html_example.html:

#!/bin/sh

fecha=`date +%F`
parrafo1='Este es el primer parrafo'
parrafo2='Este es el segundo parrafo'
parrafo3='Este es el tercer parrafo'

echo "<html>" > /home/julio/html_example.html
echo "<head><title>HTML de ejemplo</title></head>" >> /home/julio/html_example.html
echo "<h1>Este es el header principal </h1>" >> /home/julio/html_example.html
echo "<h2>Aqui incluimos una variable, su contenido es $fecha </h2>" >> /home/julio/html_example.html
echo "<p>$parrafo1</p>" >> /home/julio/html_example.html
echo "<p>$parrafo2</p>" >> /home/julio/html_example.html
echo "<p>$parrafo3</p>" >> /home/julio/html_example.html
echo "<p>Ejemplo de tabla</p>" >> /home/julio/html_example.html
echo "<table style=\"width:100%\">" >> /home/julio/html_example.html
echo "<tr>" >> /home/julio/html_example.html
echo "<td align=\"center\">Primera columna</td>" >> /home/julio/html_example.html
echo "<td align=\"center\">Segunda columna</td>" >> /home/julio/html_example.html
echo "<td align=\"center\">Tercera columna</td>" >> /home/julio/html_example.html
echo "</tr>" >> /home/julio/html_example.html
echo "<tr>" >> /home/julio/html_example.html
echo "<td align=\"center\">50</td>" >> /home/julio/html_example.html
echo "<td align=\"center\">60</td>" >> /home/julio/html_example.html
echo "<td align=\"center\">70</td>" >> /home/julio/html_example.html
echo "</tr>" >> /home/julio/html_example.html
echo "</table>" >> /home/julio/html_example.html
echo "</body>" >> /home/julio/html_example.html
echo "</html>" >> /home/julio/html_example.html

El resultado de ejecutar el script anterior generaría el fichero html_example.html con el siguiente contenido:

<html>
<head><title>HTML de ejemplo</title></head>
<h1>Este es el header principal </h1>
<h2>Aqui incluimos una variable, su contenido es 2016-01-10 </h2>
<p>Este es el primer parrafo</p>
<p>Este es el segundo parrafo</p>
<p>Este es el tercer parrafo</p>
<p>Ejemplo de tabla</p>
<table style="width:100%">
<tr>
<td align="center">Primera columna</td>
<td align="center">Segunda columna</td>
<td align="center">Tercera columna</td>
</tr>
<tr>
<td align="center">50</td>
<td align="center">60</td>
<td align="center">70</td>
</tr>
</table>
</body>
</html>

Sin embargo, incluso para obtener un resultado tan sencillo parece que hemos tenido que armar demasiado jaleo, el script es cuanto menos poco legible y si el código fuera más complejo, aún peor. Es poco productivo.

Here comes Here Document

Ahora veamos cómo nos facilita la vida el uso de Here Document, indicando un delimitador (en este caso le he dado el nombre EOF) para el código que queremos volcar en el fichero html_example.html

#!/bin/sh

fecha=`date +%F`
parrafo1="Este es el primer parrafo"
parrafo2="Este es el segundo parrafo"
parrafo3="Este es el tercer parrafo"


cat << EOF > /home/julio/html_example.html
<html>
<head><title>HTML ejemplo</title></head>
<body>
<h1>Este es el header principal</h1>
<h2>Aqui incluimos una variable, su contenido es $fecha</h2>
<p>$parrafo1</p>
<p>$parrafo2</p>
<p>$parrafo3</p>
<p>Ejemplo de tabla<p>
<table style="width:100%">
<tr>
<td align="center">Primera columna</td>
<td align="center">Segunda Columna</td>
<td align="center">Tercera columna</td>
</tr>
<tr>
<td align="center">50</td>
<td align="center">60</td>
<td align="center">70</td>
</tr>
</table>
</body>
</html>
EOF

Si ejecutamos el script el resultado será exactamente el mismo que mostré al principio pero sin haber dado tantas vueltas. Como vemos el código es más sencillo, legible y mucho más fácil de escribir. Más aún: las indentaciones y tabulaciones se respetan dentro de Here Document, mientras que con el método de “echo” tendríamos que pasar las opciones correspondientes (\n, \t etc…). Por ejemplo, veamos cómo se respetarían las tabulaciones que introducimos:

#!/bin/sh

fecha=`date +%F`
parrafo1="Este es el primer parrafo"
parrafo2="Este es el segundo parrafo"
parrafo3="Este es el tercer parrafo"


cat << EOF > /home/julio/html_example.html
<html>
        <head><title>HTML ejemplo</title></head>
        <body>
                <h1>Este es el header principal</h1>
                <h2>Aqui incluimos una variable, su contenido es $fecha</h2>
                <p>$parrafo1</p>
                <p>$parrafo2</p>
                <p>$parrafo3</p>
                <p>Ejemplo de tabla<p>
                <table style="width:100%">
                        <tr>
                                <td align="center">Primera columna</td>
                                <td align="center">Segunda Columna</td>
                                <td align="center">Tercera columna</td>
                        </tr>
                        <tr>
                                <td align="center">50</td>
                                <td align="center">60</td>
                                <td align="center">70</td>
                        </tr>
                </table>
        </body>
</html>
EOF

Al ejecutar el script obtendríamos:

<html>
	<head><title>HTML ejemplo</title></head>
	<body>
		<h1>Este es el header principal</h1>
		<h2>Aqui incluimos una variable, su contenido es 2016-01-10</h2>
		<p>Este es el primer parrafo</p>
		<p>Este es el segundo parrafo</p>
		<p>Este es el tercer parrafo</p>
		<p>Ejemplo de tabla<p>
		<table style="width:100%">
			<tr>
				<td align="center">Primera columna</td>
				<td align="center">Segunda Columna</td>
				<td align="center">Tercera columna</td>
			</tr>
			<tr>
				<td align="center">50</td>
				<td align="center">60</td>
				<td align="center">70</td>
			</tr>
		</table>
	</body>
</html>

Como regla útil, la sintaxis “genérica” que conviene recordar es la siguiente:

cat << EOF > /ruta/al/fichero_destino 
Todo este contenido sera volcado a un fichero localizado en /ruta/al/fichero_destino 
Tambien las variables como $esta se volcaran al mismo
EOF

En realidad, esto es muy útil no sólo para HTML sino para cualquier ocasión en la que tengamos que generar documentos, escribir información o código en ficheros desde scripts en Linux.