8

私が抱えている問題は、サブプロセスの Popen() の結果を標準の端末とは異なる方法で解釈する Eclipse/PyCharm にあります。すべて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 に答える