8

我遇到的问题是 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 都给了我一个空元组。

关于我可能做错了什么的任何想法?

4

1 回答 1

15

好的,找到问题了,在 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下它没有!

这对我来说是一个重要的问题——永远记住环境!

于 2010-08-13T15:35:49.337 回答