Grundsätzlich ist die Geschichte, dass ich eine Auswahl von Python-Skripten für einen Client zum Importieren und Exportieren von Batch-Jobs zwischen ihrer Operations-Datenbank und ihre Ecomms Standortdatenbank erstellt haben. das funktioniert gut. Diese Skripte schreiben nach stdout, um den Benutzer über den Status des Stapel-Skripts zu informieren.Django Subprozess live/ungepuffert Reporting von stdout aus Batch-Skripten
Ich versuche, ein Framework für diese Skripts zu erstellen, die über eine Django-Ansicht ausgeführt werden, und das Stdout auf der Webseite zu veröffentlichen, um dem Benutzer den Fortschritt dieser Stapelprozesse anzuzeigen.
der Plan war zu - rufen Sie das Batch-Skript als Subprozess und speichern Sie dann stdout und stderr in eine Datei. - gibt eine Weiterleitung an eine Anzeigeseite zurück, die alle 2 Sekunden neu geladen wird und zeilenweise den Inhalt der Datei anzeigt, in die stdout geschrieben wird.
Das Problem ist jedoch, dass die stdout/stderr-Datei nicht wirklich geschrieben wird, bis das gesamte Batch-Skript ausgeführt wurde oder Fehler aus.
Ich habe eine Reihe von Dingen ausprobiert, aber keine scheint zu funktionieren.
Der aktuelle Code wird angezeigt.
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
Ihr Problem ist Ausgabepufferung; Dies kann Ihnen helfen oder nicht, da Sie die Ausgabe nicht direkt lesen: http://stackoverflow.com/questions/803265/getting-realtime-output-using-subprocess – eternicode
Ich denke, dass ich in die Verarbeitung der Ausgabe über das Original-Skript, Setzen von Schlüsselpunkten zum Speichern einer aktualisierten Protokolldatei und Übergeben des Dateinamens als Argument an das ursprüngliche Skript ... Ich hatte gehofft, dies zu vermeiden, da es viele dieser Skripte gibt, die geändert werden müssen . – BenDog