Executa o programa com ambiente definido para variáveis em um arquivo

6

Eu gostaria de executar um programa (neste caso, o Python) com apenas as variáveis de ambiente definidas em um arquivo, digamos vars.env :

FOO=bar
X=12

Aqui está um script Python que imprime o ambiente:

import os
print os.environ

Se eu executar env -i python script.py , os.environ está vazio como esperado. Da mesma forma, se eu corro

$ env -i FOO=bar X=12 python env.py

Eu obtenho

env: {'X': '12', 'FOO': 'bar'}

No entanto, o que eu gostaria de fazer é carregar o ambiente do meu arquivo vars.env ao executar o script. Como posso conseguir isso?

EDIT: Uma coisa que eu poderia fazer é cat este arquivo env, como env -i 'cat vars.env' python env.py , mas eu preferiria ser capaz de fonte de alguma forma.

    
por mdkess 23.07.2014 / 19:29

3 respostas

3

Dado o arquivo que você mostra, você deve ser capaz de fazer:

(set -f ; IFS='
' ; env - $(cat /path/to/file) /path/to/your/program
)

Se isso não funcionar, é porque você precisa primeiro formatar o arquivo do ambiente. Aqui está um exemplo:

(set -f ; IFS='
' ; env - $(cat) printenv 
) <<\ENV
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
ENV
###OUTPUT###
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore

A princípio pensei que você poderia fazer isso através do shell - mas ele provavelmente configuraria parte do seu próprio ambiente antes de chamar seu programa. Mas posso pelo menos demonstrar que os argumentos estão atribuídos corretamente:

(set -f; IFS='
' ; env - $(cat) sh -c 'echo "$variable3"'
) <<\ENV
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
ENV
###OUTPUT###
value3 an$d s'om\e m"ore

Ainda assim, se você preferir usá-lo, veja como você pode usar o shell:

(echo '$1'; cat; echo '$2') <<\ENV |\
env - sh -s -- 'set -a' printenv
variable1=value1
variable2=value2
variable3='value3 an$d s'\''om\e m"ore'
ENV
###OUTPUT###
PWD=/home/mikeserv/test
SHLVL=1
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
_=/usr/bin/printenv

Observe que eu removi o $IFS stuff - que não é necessário dessa forma -, mas eu precisava especificar as citações no arquivo. Aqui estou essencialmente .dot sourcing stdin - lendo o |pipe como entrada - mas você pode usar qualquer arquivo. Eu uso set -a antes de ler o arquivo de entrada para definir a opção --allexport .

Isso é resultado do uso de bash sh - adiciona $PWD , $SHLVL e $_ . Com dash é um pouco melhor. E dash também não adiciona um monte de exportações, então você pode especificar o parâmetro -a na linha de comando:

(cat; echo '$1') <<\ENV |\
env - dash -sa -- printenv 
variable1=value1
variable2=value2
variable3='value3 an$d s'\''om\e m"ore'
ENV
variable1=value1
variable2=value2
variable3=value3 an$d s'om\e m"ore
PWD=/home/mikeserv/test

Apenas $PWD é exibido.

    
por 23.07.2014 / 19:57
1

Você pode fazer tudo em Python :

$ cat config.py
env = {
    'FOO' : 'bar',
    'X'   : '12',
}

$ cat test.py
import os
import config

os.environ.clear()
os.environ.update(config.env)
print os.environ

Então:

$ python test.py
{'X': '12', 'FOO': 'bar'}
    
por 23.07.2014 / 19:44
1

Outra maneira seria ler o arquivo em uma matriz e, em seguida, usar a matriz como um argumento. A vantagem em comparação ao uso de substituição de processo é que ele pode manipular valores com espaço em branco neles. Exemplo:

$ cat file
FOO=bar
X=12
var=a b c

$ IFS=$'\n' read -d '' -ra vars < file
$ env -i "${vars[@]}" python env.py
{'var': 'a b c', 'X': '12', 'FOO': 'bar'}
    
por 23.07.2014 / 19:51