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 和终端执行之间存在不一致的行为的主要内容,如果未能解决你的问题,请参考以下文章

subprocess的popen函数

将变量传递给 Subprocess.Popen

使用 subprocess.Popen 隐藏控制台

python subprocess.popen stdin.write

subprocess.wait() 不等待 Popen 进程完成(使用线程时)?

subprocess.Popen("echo $HOME"... 和 subprocess.Popen(["echo", "$HOME"]