Python子进程失败,具体取决于打开IDLE的方式

问题描述

| 在Mac OS X版本10.6.7的MacBook Pro上,我有一个简单的python脚本\'test.py \':
import subprocess
subprocess.Popen([\'xterm\'])
如果我通过使用鼠标在IDLE中打开脚本来运行该脚本,它将崩溃。如果我在终端中通过键入\'idle \'启动的IDLE中运行相同的脚本,则该脚本不会崩溃。这是怎么回事? 细节: 右键单击test.py并启动IDLE(2.6.6),以启动IDLE。它只会打开Python Shell和IDLE,不会打开test.py。我打开test.py,然后从“运行”菜单中选择“运行模块”。下面粘贴的是Python Shell中的内容底部包括以这种方式打开的IDLE的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 ================================
>>> 

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,然后从“运行”菜单中选择“运行模块”。以这种方式运行时,终端窗口将正确打开。我还使用sys.path粘贴了以下Python Shell的内容
Python 2.6.6 (r266:84292,\"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
>>>
    

解决方法

您所看到的行为差异确实与环境变量“ 3”有关。当您通过终端外壳启动IDLE时,它将从您的外壳环境中继承
PATH
值。
path_helper(8)
通过参考
/etc/paths.d/
中的条目来设置登录外壳
PATH
的默认值。在OS X 10.6上,它包括xterm所在的is8ѭ。但是,当您从Finder启动IDLE时(通过双击IDLE应用程序图标或通过使用IDLE作为默认应用程序打开文件来打开IDLE(如在测试1中所做的一样),则不涉及外壳程序,并且继承了
PATH
应用环境有所不同。在特定情况下,不参考
/etc/paths.d
,因此路径上不
/usr/X11/bin
。在两种情况下,您都应该能够看到
PATH
。对于从Finder启动的IDLE.app,您可能会看到以下内容:
>>> 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终端可能会安装一些其他路径。