GNU/Linux >> Linux Esercitazione >  >> Linux

Forzare bash a espandere le variabili in una stringa caricata da un file

Molte delle risposte utilizzando eval e echo tipo di lavoro, ma si rompono su varie cose, come più righe, tentativi di sfuggire ai metacaratteri della shell, fughe all'interno del modello non destinato ad essere espanso da bash, ecc.

Ho avuto lo stesso problema e ho scritto questa funzione di shell, che per quanto ne so, gestisce tutto correttamente. Ciò eliminerà comunque solo le nuove righe finali dal modello, a causa delle regole di sostituzione dei comandi di bash, ma non ho mai riscontrato che questo sia un problema fintanto che tutto il resto rimane intatto.

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

Ad esempio, puoi usarlo in questo modo con un parameters.cfg che in realtà è uno script di shell che imposta solo variabili e un template.txt che è un modello che usa queste variabili:

. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt

In pratica, lo utilizzo come una sorta di sistema di template leggero.


Mi sono imbattuto in quella che penso sia LA risposta a questa domanda:il envsubst comando:

echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt

Questo restituisce:hello 42 world

Se vuoi continuare a lavorare sui dati in un file destination.txt , riportalo in un file come questo:

envsubst < source.txt > destination.txt

Nel caso in cui non sia già disponibile nella tua distribuzione, è nel pacchetto GNU gettext .

@Rockallite

  • Ho scritto un piccolo script wrapper per occuparmi del problema '$'.

(A proposito, c'è una "caratteristica" di envsubst, spiegata su https://unix.stackexchange.com/a/294400/7088 per espandere solo alcune delle variabili nell'input, ma sono d'accordo che sfuggire alle eccezioni è molto più conveniente.)

Ecco il mio 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  "[email protected]"

Linux
  1. Spazi per le variabili nello script Bash?

  2. In Bash, come aggiungo una stringa dopo ogni riga in un file?

  3. Reindirizzare tutto l'output su file usando Bash su Linux?

  4. Elenca le righe di un solo file in DIFF

  5. Rimuovi una determinata riga dal file della cronologia di Bash

Sostituzione di String in Bash

Sostituzione delle variabili di ambiente in un file delle proprietà

Apri Vim dall'interno di uno script di shell Bash

Bash:aggiunge una stringa alla fine del file senza interruzioni di riga

Come verificare se un file è vuoto in Bash?

bash + leggi variabili e valori dal file tramite lo script bash