2015-04-22 8 views
6

ich das Python-Modul bin mit subprocess ein Programm aufrufen und die mögliche std Fehler auf eine bestimmte Datei mit folgendem Befehl umleiten:Subprocess Fehlerdatei

with open("std.err","w") as err: 
    subprocess.call(["exec"],stderr=err) 

Ich möchte, dass die „std.err“ Datei wird nur erstellt, wenn es Fehler gibt, aber mit dem obigen Befehl, wenn es keine Fehler gibt, wird der Code eine leere Datei erstellen. Wie kann ich Python eine Datei nur erstellen, wenn es nicht leer ist?

Ich kann nach der Ausführung prüfen, ob die Datei leer ist und falls sie entfernt wird, aber ich suchte nach einem "saubereren" Weg.

Antwort

2

Sie konnten verwenden Popen, Überprüfung stderr:

from subprocess import Popen,PIPE 

proc = Popen(["EXEC"], stderr=PIPE,stdout=PIPE,universal_newlines=True) 

out, err = proc.communicate() 
if err: 
    with open("std.err","w") as f: 
     f.write(err) 

Auf einer Seite beachten, wenn Sie über den Return-Code kümmern Sie check_call verwenden, sollten Sie es mit einem NamedTemporaryFile kombinieren könnte:

from tempfile import NamedTemporaryFile 
from os import stat,remove 
from shutil import move 

try: 
    with NamedTemporaryFile(dir=".", delete=False) as err: 
     subprocess.check_call(["exec"], stderr=err) 
except (subprocess.CalledProcessError,OSError) as e: 
    print(e) 


if stat(err.name).st_size != 0: 
    move(err.name,"std.err") 
else: 
    remove(err.name) 
+0

Danke, es funktioniert perfekt. Die einzige Sache ist, die Datei zu benennen, die sich von der var unterscheidet, die benutzt wird, um Fehler zu speichern. – Marco

+0

@Marco, True, ich kopiere einfach eingefügt, ich verwende normalerweise immer 'f'. –

0

Sie können Ihren eigenen Kontext-Manager erstellen, um die Bereinigung für Sie zu erledigen - Sie können nicht wirklich das tun, was Sie hier beschreiben, was auf die Frage hinausläuft, wie Sie in die Zukunft sehen können. So etwas wie dies (mit besserer Fehlerbehandlung, etc.):

import os 
from contextlib import contextmanager 

@contextmanager 
def maybeFile(fileName): 
    # open the file 
    f = open(fileName, "w") 
    # yield the file to be used by the block of code inside the with statement 
    yield f 
    # the block is over, do our cleanup. 
    f.flush() 
    # if nothing was written, remember that we need to delete the file. 
    needsCleanup = f.tell() == 0 
    f.close() 
    if needsCleanup: 
     os.remove(fileName) 

... und dann so etwas wie:

with maybeFile("myFileName.txt") as f: 
    import random 
    if random.random() < 0.5: 
     f.write("There should be a file left behind!\n") 

werden entweder hinter sie lassen eine Datei mit einer einzigen Textzeile in ihm, oder wird nichts zurücklassen.

Verwandte Themen