На MacBook Pro с Mac OS X версии 10.6.7 у меня есть простой python script 'test.py':
import subprocess
subprocess.Popen(['xterm'])
Если я запустил этот script, открыв его в IDLE с помощью мыши, он сработает. Если я запускаю тот же script в IDLE, который я запускаю, набрав "idle" в терминале, он не сбой. Что происходит?
Подробности:
Запустите IDLE, щелкнув правой кнопкой мыши test.py и "откройте" IDLE "(2.6.6). Он открывает только оболочку Python и IDLE, а не test.py. Я открываю test.py и выбираю" запустить модуль "из меню" Выполнить". Вложенное ниже - содержимое из оболочки Python. Внизу находится sys.path для IDLE, открытый таким образом.
Python 2.6.6 (r266:84292, May 11 2011, 21:44:06)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
****************************************************************
Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer internal loopback
interface. This connection is not visible on any external
interface and no data is sent to or received from the Internet.
****************************************************************
IDLE 2.6.6
>>> ================================ RESTART ================================
>>>
Traceback (most recent call last):
File "/Users/georgepatterson/test.py", line 2, in <module>
subprocess.Popen(['xterm'])
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 623, in __init__
errread, errwrite)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 1141, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
>>> import sys
>>> for p in sys.path: print p
/Users/georgepatterson
/Users/georgepatterson/Documents
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python26.zip
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-old
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/PyObjC
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info
>>>
Запустите IDLE через окно терминала. Откройте test.py и выберите "запустить модуль" в меню "Выполнить". При запуске таким образом окно терминала открывается должным образом. Я также вставил содержимое Python Shell с помощью sys.path.
Python 2.6.6 (r266:84292, May 11 2011, 21:44:06)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
****************************************************************
Personal firewall software may warn about the connection IDLE
makes to its subprocess using this computer internal loopback
interface. This connection is not visible on any external
interface and no data is sent to or received from the Internet.
****************************************************************
IDLE 2.6.6
>>> ================================ RESTART ================================
>>>
>>> import sys
>>> for p in sys.path: print p
/Users/georgepatterson
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python26.zip
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-old
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/PyObjC
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info
>>>
Различие в поведении, которое вы видите, действительно связано с переменной среды PATH
. Когда вы запускаете IDLE через оболочку терминала, он наследует значение PATH
из среды оболочки. path_helper(8)
задает значение по умолчанию для оболочки входа PATH
, просмотрев записи в /etc/paths.d/
. В OS X 10.6, который включает /usr/X11/bin
, где находится xterm. Однако, когда вы запускаете IDLE из Finder, либо нажав double- на значок приложения IDLE, либо открыв файл, используя IDLE в качестве приложения по умолчанию (как вы это делаете в тесте 1), оболочка не задействована, а PATH
, унаследованный окружением приложения, несколько отличается. В paticular /etc/paths.d
не проконсультируется и поэтому /usr/X11/bin
не находится на пути. Вы должны уметь видеть это, глядя на PATH
в обоих случаях. Для запуска IDLE.app из Finder вы, вероятно, увидите что-то вроде:
>>> os.environ['PATH']
'/usr/bin:/bin:/usr/sbin:/sbin'
Пока возможно изменить переменные среды по умолчанию для запущенных процессов, это редко необходимо или желательно сделать. Для этого случая самым простым решением является предоставление абсолютного пути к xterm
:
import subprocess
subprocess.Popen(['/usr/X11/bin/xterm'])
Или вы могли бы стать фаворитом, самостоятельно изменив PATH.
sys.path
здесь не имеет значения (он использовался для импорта модулей python).
Вы должны проверить переменную среды PATH: os.environ['PATH']
.
Вероятно, что терминал OS X устанавливает дополнительные пути.