2010-02-25 3 views
4

J'utilise un script pour gérer les processus sur une machine distante (SSH). Appelons-le five.pySortie de scripts python affichés uniquement à la fin lors de l'utilisation de SSH?

#!/usr/bin/python 
import time, subprocess 

subprocess.call('echo 0',shell=True) 
for i in range(1,5): 
    time.sleep(1) 
    print(i) 

Si je maintenant exécuter

ssh [email protected] five.py 

Je voudrais voir la sortie

0 
1 
2 
3 
4 

apparaissent sur ma sortie standard seconde par seconde (comme c'est ce qui se passe si vous exécutez localement). Ce qui se passe est: j'obtiens le 0 de "echo" tout de suite et le reste n'apparait qu'après la fin du programme entier. (Cela n'aide pas à imbriquer 'five.py' dans un script bash, à l'appeler par 'python five.py', ou à utiliser 'print >> sys.stdout, i').

Cela doit être lié au python ainsi écrit à stdout, puisque d'autres programmes se comportent tout à fait normal .. Une solution fonctionnelle est

import time, subprocess 
import sys 

subprocess.call('echo 0',shell=True) 
for i in range(1,5): 
    time.sleep(1) 
    sys.stdout.write(str(i)+'\n') 
    sys.stdout.flush() 

Mais il doit y avoir une meilleure solution que de changer toutes mes déclarations d'impression!

Répondre

5

Vous pouvez ajouter le -u sur la ligne de tralala comme interjay a laissé entendre

#!/usr/bin/python -u 

Vous pouvez également rouvrir stdout avec mise en mémoire tampon désactivé ou réglé à la ligne mise en mémoire tampon

import os,sys 
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) # no buffering 
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1) # line buffering 

mise en mémoire tampon Habituellement ligne est un bon choix

+0

Merci beaucoup: 'sys.stdout = os.fdopen (sys.stdout.fileno(),' w ', 1)' fonctionne très bien et devrait être plus sûr que 'python -u' –

2

Une solution possible trouvée dans another topic, suggère que j'utilise

ssh -t [email protected] ./five.py 

qui simule un terminal. Seul inconvénient, les impressions ssh

Connection to host closed. 

en outre.

0

Vous pouvez remplacer l'objet sys.stdout afin qu'il soit automatiquement vidé après chaque écriture. Cela affectera également l'instruction print. Un exemple tiré de this answer:

class flushfile(object): 
    def __init__(self, f): 
     self.f = f 
    def write(self, x): 
     self.f.write(x) 
     self.f.flush() 

import sys 
sys.stdout = flushfile(sys.stdout) 

Edit: Une autre option consiste à démarrer Python avec l'option -u, qui va forcer l'entrée et la sortie à être tamponnée.

0

Une chose que vous pourriez envisager d'utiliser puisque vous utilisez déjà Python est Paramiko, une façon beaucoup plus agréable de faire un travail SSH à distance. Voici un article sur la façon dont je l'utilise dans sa forme la plus basique.

Questions connexes