Muchas de las respuestas usan eval
y echo
tipo de trabajo, pero se rompe en varias cosas, como varias líneas, intentar escapar de los metacaracteres del shell, escapes dentro de la plantilla que no está destinada a ser expandida por bash, etc.
Tuve el mismo problema y escribí esta función de shell, que por lo que sé, maneja todo correctamente. Esto aún eliminará solo las nuevas líneas finales de la plantilla, debido a las reglas de sustitución de comandos de bash, pero nunca he encontrado que eso sea un problema siempre que 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, puedes 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 plantilla ligero.
Me topé con lo que creo que es LA respuesta a esta pregunta:el envsubst
comando:
echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt
Esto genera:hello 42 world
Si desea continuar trabajando con los datos en un archivo destination.txt
, empuja esto de vuelta a un archivo como este:
envsubst < source.txt > destination.txt
En caso de que aún no esté disponible en su distribución, está en el paquete GNU gettext
.
@Rockallite
- Escribí un pequeño script de contenedor para solucionar el problema de '$'.
(Por cierto, hay una "característica" 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 guión:
#! /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 "[email protected]"