我遇到的问题是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都给了我一个空元组。
关于我可能做错的任何想法?
答案 0 :(得分:14)
好的,发现了问题,在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下它没有!
这对我来说是一个重要的难题 - 永远记住环境!