Adia a expansão da variável para subshell

2

Meu serviço usa variáveis de ambiente extensivamente para configuração (principalmente porque é realmente fácil injetá-las em um contêiner Docker).

Eu também tenho alguns scripts de manutenção que posso executar em meu ambiente de produção. Mas como eu realmente não quero que o meu ambiente shell configurado para falar com o prod por padrão, eu tenho um script auxiliar que configura o ambiente e chama meu script de manutenção. O script auxiliar atualmente se parece com algo assim:

#!/bin/bash
export DB_NAME=foo
export DB_HOST=foo.service.local
export DB_USERNAME=testy_testerson
export DB_PASSWORD=password
export SERVICE_API_KEY=qwertyuiop
"$@"

E eu corro como bin/production_env.sh scripts/maintenance_script.sh arg1 arg2 . Isso tudo funciona muito bem.

Um dos meus scripts de manutenção é dump_db.sh , que é assim:

#!/bin/sh
pg_dump --no-owner --clean --if-exists --dbname "$DB_NAME" --host "$DB_HOST" --port "$DB_PORT" --username "$DB_USER" > "db/${RAILS_ENV}-dump.$(date +%Y-%m-%dT%H:%M:%S).sql"

Isso funciona muito bem também. Mas gostaria de poder executar comandos ad-hoc usando o ambiente configurado sem colocar essa lógica em um arquivo de script primeiro. por exemplo,

bin/production_env.sh psql --username "$DB_USER" --command 'select version()'

O problema, é claro, é que a variável DB_USER é expandida no meu shell atual, antes que a variável correta DB_USER esteja disponível.

Existe uma maneira conveniente de executar comandos ad-hoc como este, adiando a expansão de variáveis até a sub-camada? Ou está colocando meus comandos ad-hoc em um script da maneira mais fácil?

    
por Dathan 20.06.2016 / 20:36

2 respostas

2

Use eval na sua linha final e verifique se o shell pai não come o $ :

#!/bin/bash
export FOO=bar
export BAR=baz
eval "$@"

funciona assim:

wouter@gangtai:~$ ./foo.sh echo '$BAR'
baz

Para mais informações, consulte help eval .

    
por 20.06.2016 / 22:06
1

Você pode obter seu production_env.sh para testar sem argumentos (ou algum argumento único especial como -i ) e, em seguida, ler uma única linha (com -e para permitir a edição de entrada) e executá-lo. Por exemplo, mude sua última linha para:

if [ $# = 0 -a -t 0 ]
then read -p 'prod> ' -e cmd
     bash -c "$cmd"
else "$@"
fi
    
por 20.06.2016 / 21:48