开发者

Python subprocess fails, depending on how IDLE is opened

开发者 https://www.devze.com 2023-03-08 14:48 出处:网络
On a MacBook Pro with Mac OS X version 10.6.7, I have a simple python script \'test.py\': import subprocess

On a MacBook Pro with Mac OS X version 10.6.7, I have a simple python script 'test.py':

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

If I run this script by opening it in IDLE using the mouse, it crashes. If I run the same script in an IDLE that I launch by typing 'idle' in a terminal, it doesn't crash. What's going on?

Details:

Launch IDLE by right clicking test.py and "open with" IDLE (2.6.6). It only opens the Python Shell and IDLE, not test.py. I open test.py and select "run module" from the "Run" menu. Pasted below is the contents from the Python Shell. Included at the bottom is the sys.path for IDLE opened in this manner.

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/python开发者_运维技巧2.6/site-packages/setuptools-0.6c11-py2.6.egg-info
>>> 

Launch IDLE through a terminal window. Open test.py and select "run module" from the "Run" menu. When run in this manner, the terminal window is opened properly. I've pasted the contents of the Python Shell below with the sys.path also.

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
>>>


The difference in behavior you are seeing does indeed have to do with the PATH environment variable. When you start IDLE via a terminal shell, it inherits the PATH value from your shell environment. path_helper(8) sets the default value for a login shell PATH by consulting the entries in /etc/paths.d/. On OS X 10.6, that includes /usr/X11/bin, which is where xterm is located. However, when you launch IDLE from the Finder, either by double-clicking on the IDLE app icon or by opening a file using IDLE as the default app (as you are doing in test 1), a shell is not involved and the PATH inherited by the app environment is slightly different. In paticular, /etc/paths.d is not consulted and so /usr/X11/bin is not on the path. You should be able to see that by looking at PATH in both cases. For IDLE.app launched from the Finder, you'll probably see something like:

>>> os.environ['PATH']
'/usr/bin:/bin:/usr/sbin:/sbin'

While it is possible to change the default environment variables for processes launched, it is rarely necessary or desirable to do that. For this case, the simplest solution is to supply the absolute path to xterm:

import subprocess
subprocess.Popen(['/usr/X11/bin/xterm'])

Or you could get fancier by modifying PATH yourself.


sys.path is not relevant here (it's used to import python modules). You should check the PATH environment variable: os.environ['PATH'].

It's probable that the OS X terminal installs some additional paths.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号