установить переменную окружения в скрипте Python - PullRequest
45 голосов
/ 03 декабря 2011

У меня есть скрипт bash, который устанавливает переменную окружения и запускает команду

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

Теперь я хочу использовать python вместо bash, потому что я хочу вычислить некоторые аргументы, которые я передаюкоманда.

Я пробовал

putenv("LD_LIBRARY_PATH", "my_path")

и

call("export LD_LIBRARY_PATH=my_path")

, за которыми следуют

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

, но программа всегда сдается, потому что LD_LIBRARY_PATHне установлен.

Как я могу это исправить?

Спасибо за помощь!

(если я экспортирую LD_LIBRARY_PATH перед вызовом скрипта python, все работает, но я бы хотел pythonопределить путь и установить правильное значение переменной среды)

Ответы [ 4 ]

52 голосов
/ 03 декабря 2011

Баш:

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

Похоже, в 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"))
8 голосов
/ 13 марта 2013

Вы можете добавить элементы в свою среду с помощью

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

и запускать подпроцессы в оболочке (которая использует os.environ) с помощью

subprocess.call('sqsub -np ' + var1 + '/homedir/anotherdir/executable', shell=True)
1 голос
/ 07 сентября 2018

Здесь есть много хороших ответов, но вы должны любой ценой избегать передачи ненадежных переменных в подпроцесс, используя shell=True как , это риск для безопасности .Переменные могут выходить в оболочку и запускать произвольные команды!Если вы просто не можете избежать этого, по крайней мере используйте shlex.quote() в python3 для экранирования строки (если у вас есть несколько разделенных пробелом аргументов, заключите в кавычки каждый сплит вместо полной строки).

shell=False всегдапо умолчанию, где вы передаете массив аргументов.

Теперь сейф решения ...

Метод # 1

Изменение среды вашего собственного процесса -Новая среда будет применяться к самому Python и всем подпроцессам.

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

Метод # 2

Сделайте копию среды и передайте ее ребенку.Вы полностью контролируете дочернюю среду и не будете влиять на собственную среду Python.

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

Метод # 3

Только для Unix: Выполните env, чтобы установить переменную среды.Более громоздким, если у вас есть много переменных для изменения, а не portabe, но, как # 2, вы сохраняете полный контроль над Python и дочерних сред.

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

Конечно, если var1 содержит несколько разделенных пробеламиаргумент они теперь будут передаваться как один аргумент с пробелами.Чтобы сохранить исходное поведение с shell=True, вы должны составить массив команд, содержащий разделенную строку:

command = ['sqsub', '-np'] + var1.split() + ['/homedir/anotherdir/executable']
0 голосов
/ 21 января 2015

Компактное решение (при условии, что вам не нужны другие переменные среды):

call('sqsub -np {} /homedir/anotherdir/executable'.format(var1).split(),
      env=dict(LD_LIBRARY_PATH=my_path))

Использование инструмента командной строки env:

call('env LD_LIBRARY_PATH=my_path sqsub -np {} /homedir/anotherdir/executable'.format(var1).split())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...