Subprocess.Popen在Django内部调用时会与交互式程序一起挂起

问题描述 投票:3回答:4

我已经编写了一个小型Django应用程序,该应用程序根据用户输入执行一个交互式程序,并将输出作为结果返回。但是由于某种原因,子进程挂起。在对日志进行验证时,我发现必须对响应发出“ \ n”的地方,但似乎从未做出过回应。有趣的是,如果我从Django外部运行相同的代码,即从python模块或从交互式shell运行,则子过程可以顺利进行。我假设Django使用的环境中的某些设置是这里的罪魁祸首。以下是我编写的代码片段:

def runtests(test_name, selective=False, tests_file=''):
    if selective:
        run_cmd = ['runtest', '--runfromfile', tests_file, test_name]
    else:
        run_cmd = 'runtest %s' % (test_name)
    print 'Executing command .. '
    print run_cmd
    p = subprocess.Popen(run_cmd, shell=False, stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT)

    return p.stdout.read()

def result(request):
    test_name = request.GET['test_name']
    if not test_name:
        return render_to_response('webrun/execute.html', {'error_flag':True})

    in_file = os.path.abspath('webrun/log/%s_in.xml' % test_name)
    suites = dict([(field[len('suite_'):],value) 
                            for field,value in request.GET.items() 
                            if field.startswith('suite_')])
    if suites:
        _from_dict_to_xml(suites, in_file, test_name)
    output = runtests(test_name, bool(suites), in_file)

    return render_to_response('webrun/result.html', {'output':output})

我已经尝试用较旧的os.system方法替换子流程。但是,即使挂在完全相同的地方。同样,如果我从Django中执行相同的代码,也可以运行。

python django subprocess
4个回答
0
投票

subprocess documentation建议您“使用communication()而不是.stdin.write,.stdout.read或.stderr.read,以避免由于任何其他OS管道缓冲区填满并阻塞子进程而导致死锁。 “

如果使用return p.communicate()[0]而不是return p.stdout.read()可以使用吗?


0
投票

我在进行此类操作以获取水银笔尖版本时遇到了相同的问题:

import subprocess

lProcess = subprocess.Popen(["hg","tip"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
lOutput = lProcess.stdout.readline()
lTipRevision = lOutput[10:].strip()
lTipRevision = lTipRevision[:lTipRevision.find(":")].strip()
print "Repository tip version is %s" % lTipRevision

这在通过apache(mod_wsgi)运行时效果很好,但是在开发服务器中导致空白页。

我已经绕过与此相关的错误,我发现这些错误似乎已被关闭,因为它们是重复的,或者是封闭的workforme。

我对此的原始帖子可在http://groups.google.com/group/django-users/browse_thread/thread/147ffe75899fd6e?pli=1中找到>>


0
投票

我认为您的问题是“运行测试”程序所在的目录。您的视图将在该视图所在的目录中获取该模块。如果模块在其他任何位置,也可以在Popen参数列表中指定'cwd'参数。我在没有任何问题的Django开发服务器视图中使用Popen命令,因此开发服务器不是导致问题的原因。


0
投票

我的问题是我在Pycharm中运行Django。运行./manage.py runserver直接为我修复了它。

© www.soinside.com 2019 - 2024. All rights reserved.