Forzar bash para expandir variables en una cadena cargada desde un archivo

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

Paquete GNU 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))