Como eu substituo as variáveis de ambiente ao enviar um arquivo?

6

Eu gostaria de de alguma forma cuspir um arquivo (que tem referências de variáveis env) e substituir os valores reais. Isso é o que eu tentei, mas como você pode ver, não está funcionando. Alguma idéia?

-bash-3.00$ cat vars_file 
${MY_VAR}
-bash-3.00$ export MY_VAR=MY_VALUE; cat ./vars_file | xargs echo
${MY_VAR}
    
por andersonbd1 20.01.2011 / 18:27

6 respostas

9

Tópico antigo, mas esse é um problema recorrente. Aqui está uma solução usando mapfile do bash:

mateus@mateus:/tmp$ cat input.txt
a = $a
b = $b
mateus@mateus:/tmp$ echo a=$a, b=$b
a=1, b=2
mateus@mateus:/tmp$ function subst() { eval echo -E "$2"; }
mateus@mateus:/tmp$ mapfile -c 1 -C subst < input.txt
a = 1
b = 2

O bash embutido mapfile chama a função definida pelo usuário subst (veja opções -C / -c) em cada linha lida do arquivo de entrada input.txt . Como a linha contém texto sem escape, eval é usado para avaliá-lo e echo o texto transformado para stdout (-E evita que caracteres especiais sejam interpretados).

IMHO isso é muito mais elegante do que qualquer solução baseada em sed / awk / perl / regex.

Outra solução possível é usar a substituição do próprio shell. Isso parece uma maneira mais "portátil" de não transmitir em mapfile :

mateus@mateus:/tmp$ EOF=EOF_$RANDOM; eval echo "\"$(cat <<$EOF
$(<input.txt)
$EOF
)\""
a = 1
b = 2

Note que usamos $EOF para minimizar o documento aqui do gato conflitante com o conteúdo input.txt.

Ambos os exemplos de: link

EDIT: Desculpe, o primeiro exemplo não trata comentários e espaços em branco corretamente. Eu vou trabalhar nisso e postar uma solução. EDIT2: Corrigir double $ RANDOM eval

    
por 14.12.2012 / 22:54
2

Conforme descrito no mesmo tópico no link , a solução "adequada" seria a seguinte: segue:

awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < input.txt > output.txt
A abordagem

eval é boa, mas tende a falhar em arquivos XML, por exemplo.

    
por 27.06.2011 / 16:31
2

Pode ser feito com script (por exemplo, o nome do arquivo é expand.sh ):

while read line; do eval echo \"$line\"; done < $1 > $2

O script pode ser chamado assim:

env VAR1=value1 sh expand.sh input_file output_file

- link

    
por 20.01.2011 / 18:32
1

Aqui está minha solução proposta:

eval $'cat <<
eval $'cat <<
eval $'cat <<
eval $'cat <<%pre%2\n'"$(tr -d '%pre%2' < ifile)"$'\n%pre%2' > ofile
2\n'"$(<ifile)"$'\n%pre%2' > ofile
2\n'"$(tr -d '%pre%2' < ifile)"$'\n%pre%2' > ofile
2\n'"$(<ifile)"$'\n%pre%2' > ofile

$(command)2 pode ser substituído por qualquer caractere ou string que não ocorra no ifile. Para excluir quaisquer ocorrências do caractere delimitador no arquivo de entrada:

%pre%

Esta solução parece resolver a maioria dos problemas, mas é notavelmente vulnerável à injeção de comando no arquivo de modelo através das diretivas %code% .

    
por 16.01.2014 / 11:39
1

$"xxx" pode ser um caminho fácil

a=$(< file)
eval b=\$\"$a\"

então "$ b" é o texto expandido

    
por 15.09.2014 / 22:16
0

Isso define uma função de shell que usa python para imitar a expansão básica de shell de variáveis $ {name}. Eu uso-o para expandir variáveis bash incorporadas em scripts SQL. Como meu arquivo não é um arquivo bash verdadeiro, você não pode usar o eval () bash builtin

apply_shell_expansion() {
python - << EOF
import os
doc=open('${1}').read()
for k,v in os.environ.items():
  doc = doc.replace('$'+'{'+k+'}',v)
print doc
EOF
}
    
por 06.10.2017 / 05:06