Как получить текущую оболочку и выполнить в ней команду? - PullRequest
0 голосов
/ 31 мая 2018

У меня есть virtualenv по имени 'venv', и он активируется:

(venv)>

, и я написал коды, которые я запустил в virtualenv (main.py):

import subprocess
result = subprocess.run('python other.py', stdout=subprocess.PIPE)

но когда я запускаю main.py файл:

(venv)> python main.py

subprocess не выполняет команду (python other.py) в virtualenv, т.е. venv

Как запуститьsubprocess команда в текущем сеансе virtualenv?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Если вы хотите запустить сценарий с тем же исполняемым файлом Python, который используется для запуска текущего сценария, не используйте python и полагайтесь на правильно заданный путь, просто используйте sys.executable:

Строка, задающая абсолютный путь исполняемого двоичного файла для интерпретатора Python, в системах, где это имеет смысл.

Это работает, если вы выполнили сценарий сpython myscript.py полагаясь на ПУТЬ активного виртуленва.Это также работает, если вы выполнили скрипт с /usr/local/bin/python3.6, чтобы игнорировать PATH и протестировать ваш скрипт с определенным интерпретатором.Или, если вы выполнили сценарий с myscript.py, полагаясь на строку shbang, созданную во время установки с помощью setuptools.Или, если скрипт был запущен как CGI, в зависимости от конфигурации Apache.Или если вы sudo d выполнили исполняемый файл или сделали что-то еще, что повредило вашу среду.Или почти все, что можно вообразить. 1

Как объяснено в ответ Чарльза Даффи , вам все равно нужно использовать список аргументов вместо строки (или использовать shell=True, но вы редко хотите это сделать).Итак:

result = subprocess.run([sys.executable, 'other.py'], stdout=subprocess.PIPE)

1.Ну, не совсем ... Примеры того, как это не работает, включают пользовательские программы на C, которые включают интерпретатор CPython, некоторые среды для мини-Python для смартфонов, старый школьный Amiga Python, ... Наиболее вероятные, которые могут повлиять на вас- и это довольно большая протяженность - это то, что на некоторых * nix платформах, если вы пишете программу, которая exec s Python, передавая несовместимые имена для процесса и arg0, sys.executable может в итоге ошибиться.

0 голосов
/ 31 мая 2018

Дочерний процесс не может запускать команды в своем родительском процессе без участия этого процесса.

Именно поэтому ssh-agent требует использования в качестве eval "$(ssh-agent -s)" для вызова команд оболочки, которые он выдает, например, на выходе,Таким образом, буквальная вещь, которую вы просите здесь, невозможна.

К счастью, она также не нужна.


virtualenvs использует переменные среды, унаследованные дочерними процессами.

Это означает, что вам на самом деле не нужно использовать ту же оболочку, у которой активирован virtualenv, чтобы запустить новый интерпретатор Python, предназначенный для использования интерпретатора / library / etc.из этого virtualenv.


subprocess.run должен быть передан список , или shell=True должен использоваться.

Либо сделайте это (что лучше!)

import subprocess
result = subprocess.run(['python', 'other.py'], stdout=subprocess.PIPE)

или вот это (что еще хуже!)

import subprocess
result = subprocess.run('python other.py', stdout=subprocess.PIPE, shell=True)
...