GNU/Linux >> Znalost Linux >  >> Linux

Vynucení bash expandovat proměnné v řetězci načteném ze souboru

Mnoho odpovědí pomocí eval a echo druh práce, ale přerušují se různé věci, jako je více řádků, pokus o únik metaznaků shellu, úniky uvnitř šablony, které nejsou určeny k rozšíření pomocí bash atd.

Měl jsem stejný problém a napsal jsem tuto funkci shellu, která, pokud mohu říci, zpracovává vše správně. Díky pravidlům nahrazování příkazů bash to stále odstraní pouze poslední nové řádky ze šablony, ale nikdy jsem nezjistil, že by to byl problém, pokud vše ostatní zůstane nedotčeno.

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

Můžete jej například použít takto s parameters.cfg což je ve skutečnosti skript shellu, který pouze nastavuje proměnné, a template.txt což je šablona, ​​která používá tyto proměnné:

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

V praxi to používám jako jakýsi odlehčený šablonový systém.


Narazil jsem na to, co si myslím, že je odpověď na tuto otázku:envsubst příkaz:

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

Výsledkem je:hello 42 world

Pokud chcete pokračovat v práci na datech v souboru destination.txt , přesuňte to zpět do souboru, jako je tento:

envsubst < source.txt > destination.txt

V případě, že ještě není k dispozici ve vaší distribuci, je v balíčku GNU gettext .

@Rockallite

  • Napsal jsem malý obalový skript, abych se postaral o problém „$“.

(BTW, existuje "funkce" envsubst, vysvětlená na https://unix.stackexchange.com/a/294400/7088 pro rozšíření pouze některých proměnných ve vstupu, ale souhlasím s tím, že uniknout výjimkám je mnohem pohodlnější.)

Zde je můj skript:

#! /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. Hromadné přejmenování souboru Bash pomocí čítače?

  2. Bash skript k odstranění nejstaršího souboru ze složky?

  3. Jak vytvořit pole jedinečných prvků ze řetězce/pole v Bash?

  1. Prostory pro proměnné ve skriptu Bash?

  2. Jak odstraním nové řádky z textového souboru?

  3. Nahrazení proměnných prostředí v souboru vlastností

  1. Výpis řádků pouze z jednoho souboru v DIFF

  2. Odstraňte určitý řádek ze souboru historie Bash

  3. Bash skript pro odstranění nejstaršího souboru ze složky