代码之家  ›  专栏  ›  技术社区  ›  BenDog

Django子进程从批处理脚本实时/无缓冲地报告stdout

  •  1
  • BenDog  · 技术社区  · 15 年前

    基本上,后面的故事是,我为一个客户机构建了一个python脚本选择,用于在其操作数据库和ecomms站点数据库之间处理导入和导出批处理作业。这很管用。这些脚本将写入stdout以更新用户批处理脚本的状态。

    我试图为这些脚本生成一个框架,以便通过django视图运行,并将stdout发布到网页上,向用户显示这些批处理过程的进度。

    计划是 -将批处理脚本作为子进程调用,然后将stdout和stderr保存到文件中。 -返回一个重定向到显示页面,该页面将每2秒重新加载一次,并逐行显示正在写入stdout的文件的内容。

    但是问题是,在整个批处理脚本运行完毕或出错之前,stdout/stderr文件实际上不会被写入。

    我试过很多东西,但似乎都不管用。

    这是当前的视图代码。

    def long_running(app, filename):
        """where app is ['command', 'arg1', 'arg2'] and filename is the file used for output"""
        # where to write the result (something like /tmp/some-unique-id)
        fullname = temppath+filename
        f = file(fullname, "a+")
        # launch the script which outputs something slowly
        subprocess.Popen(app, stdout=f, stderr=f)# .communicate()
        # once the script is done, close the output
        f.close()
    
    def attributeexport(request):
        filename = "%d_attribute" %(int(time.time())) #set the filename to be the current time stamp plus an identifier
        app = ['python','/home/windsor/django/applications/attribute_exports.py']
        #break thread for processing.
        threading.Thread(target=long_running, args=(app,filename)).start()
        return HttpResponseRedirect('/scripts/dynamic/'+filename+'/')
        pass
    
    def dynamic(request, viewfile):
        fileobj = open(temppath+viewfile, 'r')
        results = []
        for line in fileobj:
            results.append(line)
            if '~END' in line:
                #if the process has completed
                return render_to_response('scripts/static.html', {'displaylist':results, 'filename':viewfile})
        return render_to_response('scripts/dynamic.html', {'displaylist':results, 'filename':viewfile})
    pass
    
    1 回复  |  直到 15 年前
        1
  •  1
  •   Mat    14 年前

    如果您使用以下选项,则会有所帮助:

    ['python','-u','path/to/python/script.py']