我编写了一个小型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执行相同的代码,这也会运行。
答案 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
可以直接为我修复。