subprocess.Popen() 在 Eclipse/PyCharm 和终端执行之间存在不一致的行为
Posted
技术标签:
【中文标题】subprocess.Popen() 在 Eclipse/PyCharm 和终端执行之间存在不一致的行为【英文标题】:subprocess.Popen() has inconsistent behavior between Eclipse/PyCharm and terminal execution 【发布时间】:2011-03-28 11:17:51 【问题描述】:我遇到的问题是 Eclipse/PyCharm 以不同于标准终端的方式解释子进程的 Popen() 结果。都在 OSX 上使用 python2.6.1。
这是一个简单的示例脚本:
import subprocess
args = ["/usr/bin/which", "git"]
print "Will execute %s" % " ".join(args)
try:
p = subprocess.Popen(["/usr/bin/which", "git"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# tuple of StdOut, StdErr is the responses, so ..
ret = p.communicate()
if ret[0] == '' and ret[1] <> '':
msg = "cmd %s failed: %s" % (fullcmd, ret[1])
if fail_on_error:
raise NameError(msg)
except OSError, e:
print >>sys.stderr, "Execution failed:", e
使用标准终端,行:
ret = p.communicate()
给我:
(Pdb) print ret
('/usr/local/bin/git\n', '')
Eclipse 和 PyCharm 给了我一个空元组:
ret = tuple ('','')
更改 shell= 值也不能解决问题。在终端上,设置 shell=True,并完全传递命令(即 args=["/usr/bin/which git"])给我同样的结果:ret = ('/usr/local/bin/git \n','')。 Eclipse/PyCharm 都给了我一个空元组。
关于我可能做错的任何想法?
【问题讨论】:
【参考方案1】:好的,找到了问题所在,在 Unix 类型的环境中使用 IDE 时要牢记这一点。 IDE 的运行环境与终端用户不同(对吧?!)。我没有考虑到子进程使用的环境与我的终端上下文不同(我的终端设置了 bash_profile 以在 PATH 中包含更多内容)。
这很容易通过如下更改脚本来验证:
import subprocess
args = ["/usr/bin/which", "git"]
print "Current path is %s" % os.path.expandvars("$PATH")
try:
p = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# tuple of StdOut, StdErr is the responses, so ..
out, err = p.communicate()
if err:
msg = "cmd %s failed: %s" % (fullcmd, err)
except OSError, e:
print >>sys.stderr, "Execution failed:", e
终端下,路径包括/usr/local/bin。在 IDE 下没有!
这对我来说是一个重要的问题 - 永远记住环境!
【讨论】:
哇,我在 Windows 下也遇到了同样的问题,你给我指出了正确的方向!谢谢。从控制台启动的解释器可以访问“系统”和“当前用户”$PATH 变量,而从 IDE 或资源管理器启动的解释器或程序只能访问“系统”$PATH。 让 Eclipse 包含终端可用的所有上下文的解决方案是什么?谢谢!以上是关于subprocess.Popen() 在 Eclipse/PyCharm 和终端执行之间存在不一致的行为的主要内容,如果未能解决你的问题,请参考以下文章
python subprocess.popen stdin.write
subprocess.wait() 不等待 Popen 进程完成(使用线程时)?
subprocess.Popen("echo $HOME"... 和 subprocess.Popen(["echo", "$HOME"]