2010-08-11 1 views
7

Проблема, с которой я столкнулась, заключается в том, что Eclipse/PyCharm интерпретирует результаты подпроцесса Popen() по-разному от стандартного терминала. Все используют python2.6.1 для OSX.subprocess.Popen() имеет непоследовательное поведение между Eclipse/PyCharm и выполнением терминала

Вот простой пример скрипта:

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 = True и вообще передайте команду (т. Е. Args = ["/ usr/bin/which git"]) дает мне тот же результат: ret = ('/ usr/local/bin/git \ n ',' '). И Eclipse/PyCharm дают мне пустой кортеж.

Любые идеи о том, что я могу делать неправильно?

ответ

14

Хорошо, нашел проблему, и это важно помнить при использовании среды IDE в среде типа Unix. IDE работают в другом контексте среды, чем пользователь терминала (duh, right ?!). Я не думал, что подпроцесс использует другую среду, чем контекст, который у меня есть для моего терминала (мой терминал имеет 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/местные/бен. В среде IDE это не так!

Это важный вопрос для меня - всегда помните о средах!

+0

Вау, у меня была такая же проблема под Windows, и ты указал мне в правильном направлении! Благодарю. У интерпретатора, запускаемого с консоли, есть доступ к переменным «система» и «текущий пользователь» $ PATH, тогда как интерпретатор или программа, запущенная из среды IDE или проводника, имеет доступ только к «системе» $ PATH. –

+0

Каково решение, позволяющее Eclipse включать все контексты, доступные из терминала? Благодаря! – Tarelli