Quelques règles de base pour subprocess.
- Ne jamais utiliser
shell=True. Il appelle inutilement un processus shell supplémentaire pour appeler votre programme.
- Lors de l'appel de processus, les arguments sont transmis sous forme de listes.
sys.argven python est une liste, tout comme argven C. Vous passez donc une liste à Popenpour appeler des sous-processus, pas une chaîne.
- Ne redirigez pas vers
stderrun PIPElorsque vous ne le lisez pas.
- Ne redirigez pas
stdinlorsque vous n'y écrivez pas.
Exemple:
import subprocess, time, os, sys
cmd = ["rsync.exe", "-vaz", "-P", "source/" ,"dest/"]
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, b''):
print(">>> " + line.rstrip())
Cela dit, il est probable que rsync tamponne sa sortie lorsqu'il détecte qu'il est connecté à un tube au lieu d'un terminal. C'est le comportement par défaut - lorsqu'ils sont connectés à un tube, les programmes doivent explicitement vider stdout pour les résultats en temps réel, sinon la bibliothèque C standard sera mise en mémoire tampon.
Pour tester cela, essayez d'exécuter ceci à la place:
cmd = [sys.executable, 'test_out.py']
et créez un test_out.pyfichier avec le contenu:
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
L'exécution de ce sous-processus devrait vous donner "Hello" et attendre 10 secondes avant de donner "World". Si cela se produit avec le code python ci-dessus et non avec rsync, cela signifie qu'il rsyncmet en mémoire tampon la sortie, vous n'avez donc pas de chance.
Une solution serait de se connecter directement à un pty, en utilisant quelque chose comme pexpect.