Intercalar Shell scripting con texto / HTML / XML / Markdown / etc
El pequeño pero genial script awk que se presenta en este articulo forma parte del proyecto webrc, un “anti-framework” web minimalista construido siguiendo la filosofía de diseño de Unix y Plan 9. Este script permite crear un documento en formato texto, por ejemplo xml, markdown o html, pero integrando en su contenido lógica de la terminal, es decir, intercalar dentro condiciones, variables, salidas de comandos y cualquier otra cosa que se pueda realizar en una terminal para generar contenido dinámico.
El uso es similar a como se programa en PHP, usando unas etiquetas para insertar el código entre texto. La forma de uso en este caso es agregar el carácter “%” a principio de linea para que la linea sea interpretada por una shell, la cual no necesariamente tiene que ser Bash. Es muy útil a la hora de generar informes / documentación. Veamos un ejemplo de uso práctico para entender bien la utilidad de dicho script.
Código del script template.awk: https://code.9front.org/hg/werc/file/fb460a671d19
#!/bin/awk -f function pr(str) { if(lastc !~ "[{(]") gsub(/'/, "''", str) printf "%s", str } function trans(c) { printf "%s", end lastc = c end = "\n" if(c == "%") end = "" else if(c == "(") printf "echo -n " else if(c ~ "[})]") { end = "'\n" printf "echo -n '" } } BEGIN { lastc = "{" trans("}") } END { print end } /^%/ && $0 !~ /^%[{()}%]/ && lastc !~ /[({]/ { trans("%") print substr($0, 2) next } { if(lastc == "%") trans("}") n = split($0, a, "%") pr(a[1]) for(i=2; i<=n; i++) { c = substr(a[i], 1, 1) rest = substr(a[i], 2) if((lastc !~ "[({]" && c ~ "[({]") || (lastc == "{" && c == "}") || (lastc == "(" && c == ")")) trans(c) else if(c == "%") pr("%") else pr("%" c) pr(rest) } pr("\n") }
Generar contenido html dinámico de ejemplo, se crea un fichero con nombre test que tendrá el siguiente contenido.
% # Declaración de tres variables. % nombre=Marisa % apellido=Gutiérrez % uid=`id` % # Código HTML usando variables, condiciones y comandos bash. <html> <head> <title>Web de '%($nombre $apellido%)'</title> </head> <body> % if [[ $EUID -eq 0 ]]; then # Establecemos una condición ofreciendo dos posibles salidas dependiendo del uid. El usuario es Root <b>'%($uid%)'</b><br> %else La Variable del sistema $USER dice que el usuario es %($USER%) y tiene los siguientes IDs <b>%($uid%)</b> %fi <br><br>Estos son los archivos del directorio donde se ejecutó el comando "ls -lt". <pre> % ls -lt # Ejecución de un comando de Linux que listará el directorio actual y quedará entre etiquetas <pre> </pre> </body> </html>
Ejecutamos de la siguiente manera el fichero test.
./template.awk test | bash
El resultado como se puede ver es el código html con el contenido dinámico generado mediante instrucciones shell (variables locales, variables de entorno, condición y salida del comando ls).
<html> <head> <title>Web de Marisa Gutierrez</title> </head> <body> La Variable del sistema $USER dice que el usuario es Mari y tiene los siguientes IDs <b>uid=1000(Mari) gid=1000(Mari) grupos=1000(Mari),108(vboxusers)</b> <br><br>Estos son los archivos del directorio donde se ejecutó el comando "ls -lt". <pre> total 9275784 -rw-r--r-- 1 Mari Mari 777 mar 30 21:38 test -rw-r--r-- 1 Mari Mari 13834 mar 30 21:35 backup.log drwxr-xr-x 6 Mari Mari 4096 mar 30 21:28 Backups_web -rw-r--r-- 1 Mari Mari 60198 mar 30 21:28 calendar.ics ... </pre> </body> </html>