2011-09-12 5 views
12

Je peux rediriger avec succès ma sortie vers un fichier, mais cela semble écraser les données existantes du fichier:append subprocess.Popen sortie dans le fichier?

import subprocess 
outfile = open('test','w') #same with "w" or "a" as opening mode 
outfile.write('Hello') 
subprocess.Popen('ls',stdout=outfile) 

va supprimer la ligne 'Hello' du fichier. Je suppose qu'une solution consiste à stocker la sortie ailleurs comme une chaîne ou quelque chose (ce ne sera pas trop long), et l'ajouter manuellement avec outfile.write(thestring) - mais je me demandais s'il me manque quelque chose dans le module qui facilite ce.

Répondre

12

Vous pouvez ajouter la sortie de subprocess.Popen dans un fichier, et j'en utiliser quotidiennement. Voilà comment je le fais:

log = open('some file.txt', 'a') # so that data written to it will be appended 
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True) 

(bien sûr, ceci est un exemple fictif, je ne suis pas à l'aide subprocess à la liste des fichiers ...)

Par ailleurs, tout objet avec write() peut remplacer cet objet log, de sorte que vous pouvez mettre en tampon la sortie, et faire ce que vous voulez avec (écrire dans un fichier, afficher, etc) à l'intérieur de cet objet de type fichier.

Note: ce qui peut être trompeur, c'est le fait que subprocess, pour une raison que je ne comprends pas, écrira avant ce que vous voulez écrire. Donc, voici la façon d'utiliser ceci:

log = open('some file.txt', 'a') 
log.write('some text, as header of the file\n') 
log.flush() # <-- here's something not to forget! 
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True) 

Ainsi, l'indice est: ne pas oublier de flush la sortie!

+0

Note sur le poste ci-dessus: après quelques essais, il semble que 'subprocess.Popen' a besoin de quelque chose qui ressemble vraiment à un fichier pour ses arguments' stdout' et 'stderr', donc leur donner un objet personnalisé avec seulement une méthode' write' n'est pas suffisant. J'ai essayé, mais une fonction 'fileno' est nécessaire, et je ne suis pas assez bon pour l'imiter dans une classe à moi. –

+2

J'ai essayé d'utiliser cette méthode mais j'ai découvert que pour une raison quelconque, chaque fois que j'exécute le processus externe avec un fichier que j'ai définitivement ouvert pour l'ajouter, la sortie du processus écrit depuis le début du fichier et écrase toute information là-bas. Donc, pour utiliser cette solution, il faut appeler log.seek (0, os.SEEK_END) immédiatement après avoir ouvert le fichier. – Luke

0

Les données du fichier sont-elles réellement écrasées? Sur mon hôte Linux j'ai le comportement suivant: 1) l'exécution de votre code dans le répertoire distinct obtient:

$ cat test 
test 
test.py 
test.py~ 
Hello 

2) si j'ajoute outfile.flush() après outfile.write('Hello'), les résultats est légèrement différente:

$ cat test 
Hello 
test 
test.py 
test.py~ 

Mais le fichier de sortie a Hello dans les deux cas. Sans explicite flush(), le tampon d'appel stdout sera vidé lorsque le processus python est terminé. Où est le problème?

0

Eh bien, le problème est que si vous voulez que l'en-tête à tête, alors vous devez rincer avant que le reste de la production est écrit dans le fichier: D

Questions connexes