ti-enxame.com

definir variável de ambiente no script python

Eu tenho um script bash que define uma variável de ambiente e executa um comando

LD_LIBRARY_PATH=my_path
sqsub -np $1 /homedir/anotherdir/executable

Agora eu quero usar python em vez de bash, porque quero calcular alguns dos argumentos que estou passando para o comando.

Eu tentei

putenv("LD_LIBRARY_PATH", "my_path")

e

call("export LD_LIBRARY_PATH=my_path")

seguido por

call("sqsub -np " + var1 + "/homedir/anotherdir/executable")

mas sempre o programa desiste porque LD_LIBRARY_PATH não está definido.

Como posso consertar isso?

Obrigado pela ajuda!

(se eu exportar LD_LIBRARY_PATH antes de chamar o script python _ tudo funciona, mas eu gostaria que python _ determinasse o caminho e definisse a variável de ambiente com o valor correto)

48
Matthias 009

bater:

LD_LIBRARY_PATH=my_path
sqsub -np $1 /path/to/executable

Similar, em Python:

import os
import subprocess
import sys

os.environ['LD_LIBRARY_PATH'] = "my_path" # visible in this process + all children
subprocess.check_call(['sqsub', '-np', sys.argv[1], '/path/to/executable'],
                      env=dict(os.environ, SQSUB_VAR="visible in this subprocess"))
54
jfs

Você pode adicionar elementos ao seu ambiente usando

os.environ['LD_LIBRARY_PATH'] = 'my_path'

e execute subprocessos em um Shell (que usa seu os.environ) usando

subprocess.call('sqsub -np ' + var1 + '/homedir/anotherdir/executable', Shell=True)
11
Manbeardo

Há muitas boas respostas aqui, mas você deve evitar a todo custo passar variáveis ​​não confiáveis ​​para o subprocesso usando Shell=True como esse é um risco à segurança. As variáveis ​​podem escapar para o Shell e executar comandos arbitrários! Se você simplesmente não pode evitá-lo, use pelo menos shlex.quote() do python3 para escapar da string (se você tiver vários argumentos separados por espaço, cite cada divisão em vez da string completa).

Shell=False é sempre o padrão em que você passa uma matriz de argumentos.

Agora as soluções seguras ...

Método 1

Altere o ambiente do seu próprio processo - o novo ambiente será aplicado a próprio python e todos os subprocessos.

os.environ['LD_LIBRARY_PATH'] = 'my_path'
command = ['sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command)

Método # 2

Faça uma cópia do ambiente e passe para as crianças. Você tem controle total sobre o ambiente filho e não afetará o próprio ambiente do python.

myenv = os.environ.copy()
myenv['LD_LIBRARY_PATH'] = 'my_path'
command = ['sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command, env=myenv)

Método # 3

Somente Unix: Execute env para definir a variável de ambiente. Mais complicado se você tiver muitas variáveis ​​para modificar e não usar, mas como o número 2, você mantém controle total sobre os ambientes python e filhos.

command = ['env', 'LD_LIBRARY_PATH=my_path', 'sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command)

Obviamente, se var1 contiver vários argumentos separados por espaço, eles serão passados ​​como um único argumento com espaços. Para manter o comportamento original com Shell=True, você deve compor uma matriz de comandos que contenha a cadeia de caracteres dividida:

command = ['sqsub', '-np'] + var1.split() + ['/homedir/anotherdir/executable']
1
Thomas Guyot-Sionnest