2016-12-17 4 views
0

Следующий код позволяет мне динамически определять и загружать пользовательский модуль, если он не находится ни в одном из директории переменной sys.pathустановка PYTHONPATH внутри питона сценария с помощью subprocess.Popen() терпит неудачу

import sys 
sys.path.append("/lib") 

Но это дает мне OSError

import subprocess 
x = subprocess.Popen(["export", "PYTHONPATH=/lib"], stdout=subprocess.PIPE) 

не только это, даже простой Linux/Unix переменная установка декларации терпит неудачу в subprocess.Popen()

import subprocess 
x = subprocess.Popen("x=y", stdout=subprocess.PIPE) 

Я хотел проверить подпроцесс, как я попытался установить PYTHONPATH через os.system(), os.popen() и т.д., а переменный не установлен (может быть он установлен в дочернем процессе оболочке)

+0

'export' - это встроенная команда оболочки, а не программа. В любом случае, установка его в дочернем процессе не повлияет на текущий процесс python. Вам нужно «os.environ» https://docs.python.org/3/library/os.html?highlight=environ#os.environ. – cdarke

+0

os.environ ["PYTHONPATH"] = "/ dir" и subprocess.call (["export PYTHONPATH =/dir"], shell = True) Оба кода помогают мне установить переменную окружения PYTHONPATH, но даже после настройки я не мог загрузить модуль, присутствующий в этом каталоге, и я не вижу ввода этой записи в каталог переменной sys.path –

+1

'subprocess.call ([" export PYTHONPATH =/dir "], shell = True)' будет влиять только что один дочерний процесс - переменные окружения не являются глобальными, они не разделены, они * скопированы * от родителя к дочернему. Установка 'os.environ [" PYTHONPATH "] ="/dir "' не будет устанавливать 'sys.path' текущего процесса, потому что PYTHONPATH считывается при запуске процесса, а не позже. – cdarke

ответ

1

Попробуйте следующее:

>>> subprocess.call(["export foo=bar && echo foo=$foo"], shell=True) 
foo=bar 
0 
>>> 
1

Есть несколько вещей, которые здесь происходят, и, вероятно, вас немного смущает. Одно дело, что любые инструкции, данные Popen, будут исполняться в дочернем процессе и не повлияют на ваш основной процесс. Вы можете просто вывести или извлечь из него результаты.

Сначала прокомментируйте ваш второй вариант использования, в котором вы используете строку в качестве аргумента. Из документов вы можете прочитать:

класса subprocess.Popen (арг, BUFSIZE = -1, исполняемым = None, STDIN = None, STDOUT = None, STDERR = None, preexec_fn = None, close_fds = True, оболочки = False, УХО = None, ENV = None, universal_newlines = False, STARTUPINFO = None, creationflags = 0, restore_signals = True, start_new_session = False, pass_fds =())

...

Арги должны быть последовательность аргументов программы или одну строку . По умолчанию программа для выполнения является первым элементом в args , если args - это последовательность. Если args является строкой, интерпретация зависит от платформы и описывается ниже. См. Аргументы оболочки и исполняемого файла для дополнительных отличий от поведения по умолчанию. Если не указано иное , рекомендуется передать args в виде последовательности.

В POSIX, , если args является строкой, строка интерпретируется как имя или путь к исполняемой программе. Однако это можно сделать только в том случае, если не передает аргументы программе.

Итак, во втором случае вы пытаетесь выполнить файл или программу x = y, которая не идет.

Даже если вы используете список, как в вашем первом случае, вы должны знать, что это не эквивалентно передаче кода в оболочку bash. Если вы хотите этого, вы можете использовать shell = True как аргумент ключевого слова, но это имеет другие проблемы, как указано в документах. Но ваш код будет выполнить с shell = True.

Если ваша единственная цель состоит в том, чтобы установить переменную окружения, то вам следует рассмотреть возможность использования os.environ переменную, которая отображает ваши переменные окружения для значений (как обозначено @cdarke первой).

Смежные вопросы