Я использую subprocess.Popen
для вызова внешнего скрипта Python из моего установленного Приложения, связанного с помощью PyInstaller.
Формат этой команды примерно такой:
subprocess.Popen(["/usr/bin/python", "/path/to/exe/SDK.py"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=False)
Я успешно проверил это на Windows и MacOS - оба могут запустить внешний скрипт. Однако на других ОС Posix я получаю следующую ошибку:
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
ImportError: No module named site
Теперь я понимаю, что этот вопрос задавался ранее, и обычно он имеет значение PYTHONHOME
с неправильным значением. Однако, если я запускаю команду в формате, похожем на:
PYTHONHOME=/usr /usr/bin/python /path/to/exe/SDK.py
Я не получаю ошибок в журналах, но скрипт SDK.py не выполняется.
Поэтому, чтобы доказать, что это не проблема с моим сценарием; Я установил свою собственную версию Python на компьютер - после этого сценарий был успешно выполнен. Я проверил как /usr/bin/python
, так и /home/vagrant/Python-2.7.15/python
, без необходимости указывать PYTHONHOME
в команде подпроцесса.
Однако мне все еще нужно разрешить пользователям выполнять сценарий SDK.py с использованием встроенной версии Python для ОС.
Итак, чтобы сделать это, я попробовал другие вещи:
- Использование
sys.executable
в вызове subprocess.Popen
для выполнения
SDK.py.
(значение которого было: /opt/program_name/lib/program_name
)
Принудительное заполнение PYTHONPATH
& PYTHONHOME
путем явной настройки среды:
import os
env = os.environ.copy()
env['PYTHONHOME'] = ''
env['PYTHONPATH'] = ''
subprocess.Popen(["/usr/bin/python", "/path/to/exe/SDK.py"], env=env)
Кто-нибудь может объяснить, как я могу вызвать системную версию Python из внешнего подпроцесса, как этот?
EDIT:
Вывод при вызове Python в подробном режиме (из CLI):
>>> from sys import executable
>>> executable
'/usr/bin/python'
>>> import _csv
# trying _csv.so
# trying _csvmodule.so
# trying _csv.py
# trying _csv.pyc
# trying /usr/lib64/python2.7/_csv.so
# trying /usr/lib64/python2.7/_csvmodule.so
# trying /usr/lib64/python2.7/_csv.py
# trying /usr/lib64/python2.7/_csv.pyc
# trying /usr/lib64/python2.7/plat-linux2/_csv.so
# trying /usr/lib64/python2.7/plat-linux2/_csvmodule.so
# trying /usr/lib64/python2.7/plat-linux2/_csv.py
# trying /usr/lib64/python2.7/plat-linux2/_csv.pyc
# trying /usr/lib64/python2.7/lib-dynload/_csv.so
dlopen("/usr/lib64/python2.7/lib-dynload/_csv.so", 2);
import _csv # dynamically loaded from /usr/lib64/python2.7/lib-dynload/_csv.so