从Django内部调用时,Subprocess.Popen挂起了交互式程序

时间:2010-08-06 10:10:25

标签: python django subprocess

我编写了一个小型Django App,它根据用户输入执行交互式程序,并将输出作为结果返回。但由于某种原因,子进程挂起。在验证日志时,我发现一个地方必须给出'\ 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方法替换subprocess。但即便如此,也会挂在同一个地方。同样,如果我从Django执行相同的代码,这也会运行。

4 个答案:

答案 0 :(得分:0)

subprocess documentation建议您“使用communic()而不是.stdin.write,.stdout.read或.stderr.read来避免因任何其他OS管道缓冲区填满和阻塞而导致的死锁儿童过程。“

如果您使用return p.communicate()[0]代替return p.stdout.read()吗?

答案 1 :(得分:0)

我有同样的问题做这种事情来获得mercurial tip版本:

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

找到

答案 2 :(得分:0)

我认为你的问题是'runtest'程序所在的目录。您将查看视图将在视图所在的同一目录中获取该模块。如果模块位于其他任何位置,您还可以在Popen参数列表中指定'cwd'参数。 我在Django dev服务器的视图中使用Popen命令没有任何问题,所以开发服务器不是你的问题的原因。

答案 3 :(得分:0)

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