Сбой подпроцесса Python, в зависимости от того, как открыт IDLE - PullRequest
1 голос
/ 25 мая 2011

На MacBook Pro с Mac OS X версии 10.6.7 у меня есть простой скрипт на python 'test.py':

import subprocess
subprocess.Popen(['xterm'])

Если я запускаю этот скрипт, открывая его в IDLE с помощью мыши, он вылетает. Если я запускаю тот же сценарий в 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's 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 ниже также в 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's 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
>>>

Ответы [ 2 ]

2 голосов
/ 03 июня 2011

Различие в поведении, которое вы видите, действительно связано с переменной окружения PATH. Когда вы запускаете IDLE через терминальную оболочку, она наследует значение PATH из вашей оболочки. path_helper(8) устанавливает значение по умолчанию для оболочки входа PATH, обращаясь к записям в /etc/paths.d/. На OS X 10.6 это включает /usr/X11/bin, где находится xterm. Однако, когда вы запускаете IDLE из Finder, либо дважды щелкнув значок приложения IDLE, либо открыв файл с использованием IDLE в качестве приложения по умолчанию (как вы делаете в тесте 1), оболочка не включается, и PATH Наследуется средой приложения немного по-другому. В частности, к /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 самостоятельно.

1 голос
/ 03 июня 2011

sys.path здесь не имеет значения (используется для импорта модулей Python).Вы должны проверить переменную среды PATH: os.environ['PATH'].

Возможно, что терминал OS X установит несколько дополнительных путей.

...