Acredito que executar um comando externo com um ambiente ligeiramente modificado é um caso muito comum. É assim que eu faço:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
Tenho a sensação de que há uma maneira melhor; parece bem?
python
subprocess
popen
Oren_H
fonte
fonte
os.pathsep
vez de ":" para caminhos que funcionam entre plataformas. Veja stackoverflow.com/questions/1499019/…/usr/sbin
:-)Respostas:
Eu acho que
os.environ.copy()
é melhor se você não pretende modificar o os.environ para o processo atual:fonte
os.environ.copy
para aenv
variável, mas você precisa para atribuir o resultado de chamar o métodoos.environ.copy()
aenv
.shell=True
suasubprocess.Popen
chamada. Observe que existem potencialmente implicações de segurança para fazer isso.my_command
é apenas um comando para executar. Pode ser, por exemplo,/path/to/your/own/program
ou qualquer outra declaração "executável".Isso depende de qual é o problema. Se for para clonar e modificar o ambiente, uma solução pode ser:
Mas isso depende um pouco do fato de as variáveis substituídas serem identificadores python válidos, o que geralmente é (com que frequência você encontra nomes de variáveis de ambiente que não são alfanuméricos + sublinhado ou variáveis que começam com um número?).
Caso contrário, você poderá escrever algo como:
No caso muito estranho (com que frequência você usa códigos de controle ou caracteres não-ascii em nomes de variáveis de ambiente?) Que as chaves do ambiente são as que
bytes
você não pode (no python3) usar essa construção.Como você pode ver as técnicas (especialmente a primeira) usadas aqui, os benefícios nas chaves do ambiente são normalmente identificadores python válidos e também conhecidos antecipadamente (no momento da codificação), a segunda abordagem tem problemas. Nos casos em que esse não é o caso, você provavelmente deve procurar outra abordagem .
fonte
dict(mapping, **kwargs)
. Eu pensei que era ou. Nota: ele é copiadoos.environ
sem modificá-lo, conforme sugerido por Daniel Burke na resposta atualmente aceita, mas sua resposta é mais sucinta. No Python 3.5+ você pode até fazerdict(**{'x': 1}, y=2, **{'z': 3})
. Veja pep 448 .você pode usar em
my_env.get("PATH", '')
vez demy_env["PATH"]
, casoPATH
não esteja definido de alguma forma no ambiente original, mas que não seja o que parece ser bom.fonte
Com o Python 3.5, você pode fazer o seguinte:
Aqui terminamos com uma cópia
os.environ
e umPATH
valor substituído .Foi possível pelo PEP 448 (Generalizações adicionais de desempacotamento).
Outro exemplo. Se você possui um ambiente padrão (por exemplo
os.environ
) e um ditado com o qual deseja substituir os padrões, você pode expressá-lo assim:fonte
Para definir temporariamente uma variável de ambiente sem precisar copiar o objeto os.envrion, etc, faço isso:
fonte
O parâmetro env aceita um dicionário. Você pode simplesmente pegar o os.environ, adicionar uma chave (sua variável desejada) (a uma cópia do ditado, se necessário) e usar como parâmetro para
Popen
.fonte
os.environ['SOMEVAR'] = 'SOMEVAL'
Sei que isso já foi respondido há algum tempo, mas há alguns pontos que alguns podem querer saber sobre o uso de PYTHONPATH em vez de PATH em sua variável de ambiente. Descrevi uma explicação da execução de scripts python com cronjobs que lida com o ambiente modificado de uma maneira diferente ( encontrada aqui ). Achei que seria de alguma utilidade para quem, como eu, precisava de um pouco mais do que a resposta fornecida.
fonte
Em certas circunstâncias, você pode querer passar apenas as variáveis de ambiente de que seu subprocesso precisa, mas acho que você teve a idéia certa em geral (é assim que eu também faço).
fonte