2010-08-16 7 views
2

J'ai un simple script python qui prend juste un nom de fichier et crache une version modifiée de ce fichier. Je voudrais rediriger stdout (en utilisant '>' de la ligne de commande) afin que je puisse utiliser mon script pour écraser un fichier avec mes modifications, par ex. Lorsque je fais cela, le fichier test.txt résultant ne contient aucun texte du test.txt d'origine - juste les ajouts effectués par myScript.py. Toutefois, si je ne redirige pas stdout, les modifications sont correctement répercutées.Utilisation de la redirection Linux pour remplacer le fichier à partir du script Python

Pour être plus précis, voici un exemple:


myScript.py:

#!/usr/bin/python 
import sys 

fileName = sys.argv[1] 
sys.stderr.write('opening ' + fileName + '\n') 

fileHandle = file(fileName) 
currFile = fileHandle.read() 
fileHandle.close() 

sys.stdout.write('MODIFYING\n\n' + currFile + '\n\nMODIFIED!\n') 

test.txt

Hello World 

Résultat de python myScript.py test.txt > test.txt:

MODIFYING 



MODIFIED! 

Répondre

7

La raison pour laquelle il fonctionne de cette façon est que, avant Python commence même, Bash interprète l'opérateur de redirection et ouvre un flux de sortie pour écrire stdout au fichier. Cette opération tronque le fichier à la taille 0 - en d'autres termes, il efface le contenu du fichier. Ainsi, au moment où votre script Python démarre, il voit un fichier d'entrée vide.

La solution la plus simple consiste à rediriger stdout vers un fichier différent, puis de le renommer en le renommant par défaut.

python myScript.py test.txt > test.out && mv test.out test.txt 

Sinon, vous pouvez modifier votre script Python pour écrire les données modifiées dans le fichier lui-même, de sorte que vous ne voudriez pas avoir à rediriger la sortie standard du tout.

+0

Correct. Ou une solution alternative. Donnez au script Python un argument à modifier au lieu d'imprimer simplement la sortie. – Wolph

+0

@WoLpH: Je crois que vous avez fait votre commentaire pendant que j'édiquais cette idée même dans la réponse ;-) –

+0

En effet, je l'ai fait. Solution parfaite, mais vous avez déjà eu mon +1;) – Wolph

1

Essayez de le rediriger vers un nouveau fichier, l'opérateur de redirection supprime probablement le fichier juste avant l'ajout.

1

L'utilitaire sponge présent dans le package moreutils dans Debian peut gérer cela gracieusement.

python myScript.py test.txt | sponge test.txt 

Comme son nom l'indique, sponge sera drainez son entrée standard complètement avant d'ouvrir test.txt et l'écriture sur le contenu complet de stdin.

Vous pouvez obtenir la dernière version de l'éponge here. La page d'accueil de moreutils est here.

Questions connexes