2015-04-22 11 views
6

sto usando il modulo python subprocess di chiamare un programma e reindirizzare l'eventuale errore std a un file specifico con il seguente comando:sottoprocesso file di errore

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

voglio che il file "std.err" viene creato solo se ci sono errori, ma usando il comando precedente se non ci sono errori il codice creerà un file vuoto. Come posso creare Python per creare un file solo se non è vuoto?

Posso controllare dopo l'esecuzione se il file è vuoto e nel caso rimuoverlo, ma stavo cercando un modo "più pulito".

risposta

2

Si potrebbe utilizzare Popen, controllando 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) 

Su un lato nota, se vi preoccupate per il codice di ritorno si dovrebbe usare check_call, è possibile combinare con un NamedTemporaryFile:

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

Grazie funziona perfettamente. L'unica cosa è denominare il file diverso dalla var utilizzata per memorizzare gli errori. – Marco

+0

@Marco, vero, ho appena copiato, io uso sempre normalmente 'f'. –

0

Puoi creare il tuo gestore di contesto personale per gestire la pulizia per te - non puoi davvero fare quello che stai descrivendo qui, che si riduce a chiedere come puoi vedere nel futuro. Qualcosa di simile (con una migliore gestione errore, ecc):

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) 

... e poi qualcosa di simile:

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

vi sia lasciarsi alle spalle un file con una sola riga di testo in esso, o non lascerà nulla dietro.