GNU/Linux >> Tutoriales Linux >  >> Linux

Obligar a bash a expandir las variables en una cadena cargada desde un archivo

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]"

Linux
  1. ¿Renombrar en masa el archivo Bash con el contador?

  2. Bash Script para eliminar el archivo más antiguo de una carpeta?

  3. ¿Cómo crear una matriz de elementos únicos a partir de una cadena/matriz en Bash?

  4. ¿Usando una referencia a una variable de cadena Bash en Sed?

  5. ¿Espacios para variables en Bash Script?

Sustitución de cadena en Bash

En Bash, ¿cómo agrego una cadena después de cada línea en un archivo?

Abra Vim desde dentro de un script de shell Bash

Bash:agregue una cadena al final del archivo sin salto de línea

¿Cómo verificar si un archivo está vacío en Bash?

Bash script para eliminar el archivo más antiguo de una carpeta