Итак, у меня есть следующая ситуация. Мне нужно динамически редактировать PYTHONPATH на целевом ПК. Теперь структура проекта:
trunk
bin
start_script
dependencies
dependencies
Из python я мог бы сделать, начиная с start_script:
root_path = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0]
dependencies_root = os.path.join(root_path, 'dependencies')
from sys import path
path.extend([root_path, dependencies_root])
Это сделало бы трюк, но мне нужно начать новые процессы python с process.Popen и изменения в sys.path ушли к тому времени, кажется.
Теперь я думал, что сценарий sh будет лучше работать здесь, к сожалению, я здесь полный noob и понятия не имею, как действовать дальше. Шестнадцатый скрипт должен делать в основном то, что сделал питон сверху, так что:
[1] Get the absolute path of the directory the script is located
[2] Get the parent of that folder (say parent_path)
[3] export PYTHONPATH=$PYTHONPATH:parent_path
[4] python start_script.py
Поэтому в основном первые два шага - это те, с которыми мне нужна помощь. Также, если есть способ внести изменения в python sys.path, сохраняются в подпроцессе, открытом с помощью subprocess.Popen, пожалуйста, дайте мне знать.
Вы можете просто обновить переменную среды PYTHONPATH
в тот же момент, когда вы обновите sys.path
в start_script, используя os.environ
dict.
Я бы использовал файл .pth
. См. Http://docs.python.org/install/index.html#inst-search-path
Файл .pth
- это файл, состоящий из одного пути каталога в строке. Он вставляет перечисленные каталоги в ваш путь к python.
Это может быть лучше, чем выполнение сценариев оболочки со всеми его недостатками (более сложная установка, разрывная переносимость и т.д.),
Почему бы не использовать аргумент env
для subprocess.Popen?
class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
Если env не None, это должно быть сопоставление, определяющее переменные среды для нового процесса; они используются вместо наследования текущей рабочей среды, которая является поведением по умолчанию.
Или, если вы просто хотите запустить процесс python, вы можете просто использовать модуль многопроцессорности.
Пример из документов:
from multiprocessing import Process
def f(name):
print 'hello', name
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
start_script.py
?
PYTHONPATH
в тот же момент, когда вы обновляетеsys.path
в start_script, используяos.environ
.realpath
, но в OSX, например, это не стандартно. Que Ларри Уолл цитирует здесь: «Легче написать переносную оболочку, чем написать сценарий переносимой оболочки».