Estoy tratando de averiguar cómo hacer que bash (force?) Expanda variables en una cadena (que se cargó desde un archivo).
Tengo un archivo llamado “algo.txt” con los contenidos:
hello $FOO world
Entonces corro
export FOO=42 echo $(cat something.txt)
esto vuelve:
hello $FOO world
No expandió $ FOO aunque la variable estaba configurada. No puedo evaluar o fuente el archivo, ya que tratará de ejecutarlo (no es ejecutable tal como está). Solo quiero la cadena con las variables interpoladas.
¿Algunas ideas?
Me encontré con lo que creo que es LA respuesta a esta pregunta: el comando envsubst
.
envsubst < something.txt
En caso de que todavía no esté disponible en su distribución, está en el
gettext
. @Rockallite: escribí un pequeño script de contenedor para encargarme del problema '\ $'.
(Por cierto, hay una "función" de envsubst, explicada en https://unix.stackexchange.com/a/294400/7088 para expandir solo algunas de las variables en la entrada, pero estoy de acuerdo en que escapar de las excepciones es mucho más conveniente.)
Aquí está mi script:
#! /bin/bash ## -*-Shell-Script-*- CmdName=${0##*/} Usage="usage: $CmdName runs envsubst, but allows '\$' to keep variables from being expanded. With option -sl '\$' keeps the back-slash. Default is to replace '\$' with '$' " if [[ $1 = -h ]] ;then echo -e >&2 "$Usage" ; exit 1 ;fi if [[ $1 = -sl ]] ;then sl='\' ; shift ;fi sed 's/\\\$/\${EnVsUbDolR}/g' | EnVsUbDolR=$sl\$ envsubst "$@"
Muchas de las respuestas utilizan el tipo de trabajo eval
y echo
, pero interrumpen varias cosas, como varias líneas, intentan escapar de los metacaracteres del shell, escapan dentro de la plantilla no pensadas para ser expandidas por bash, etc.
Tuve el mismo problema, y escribí esta función de shell, que hasta donde sé, maneja todo correctamente. Esto aún quitará solo nuevas líneas de la plantilla, debido a las reglas de sustitución de comandos de bash, pero nunca he encontrado que eso sea un problema mientras todo lo demás permanezca intacto.
apply_shell_expansion() { declare file="$1" declare data=$(< "$file") declare delimiter="__apply_shell_expansion_delimiter__" declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter" eval "$command" }
Por ejemplo, puede usarlo así con un parameters.cfg
que en realidad es un script de shell que solo establece variables, y un template.txt
que es una plantilla que usa esas variables:
. parameters.cfg printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt
En la práctica, uso esto como una especie de sistema de plantillas livianas.
puedes probar
echo $(eval echo $(cat something.txt))