Einige Faustregeln für subprocess.
- Niemals benutzen
shell=True. Es ruft unnötig einen zusätzlichen Shell-Prozess auf, um Ihr Programm aufzurufen.
- Beim Aufrufen von Prozessen werden Argumente als Listen weitergegeben.
sys.argvin Python ist eine Liste, ebenso wie argvin C. Sie übergeben also eine Liste , Popenum Unterprozesse aufzurufen, keine Zeichenfolge.
- Leiten Sie nicht
stderrzu a um, PIPEwenn Sie es nicht lesen.
- Leiten Sie nicht um,
stdinwenn Sie nicht darauf schreiben.
Beispiel:
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())
Das heißt, es ist wahrscheinlich, dass rsync seinen Ausgang puffert, wenn es erkennt, dass es mit einer Pipe anstelle eines Terminals verbunden ist. Dies ist das Standardverhalten. Wenn eine Verbindung zu einer Pipe besteht, müssen Programme stdout explizit leeren, um Echtzeitergebnisse zu erhalten. Andernfalls wird die Standard-C-Bibliothek gepuffert.
Um dies zu testen, führen Sie stattdessen Folgendes aus:
cmd = [sys.executable, 'test_out.py']
und erstellen Sie eine test_out.pyDatei mit dem Inhalt:
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
Wenn Sie diesen Unterprozess ausführen, sollten Sie "Hallo" erhalten und 10 Sekunden warten, bevor Sie "Welt" geben. Wenn dies mit dem obigen Python-Code und nicht mit passiert rsync, bedeutet dies, dass die rsyncAusgabe selbst gepuffert wird, sodass Sie kein Glück haben.
Eine Lösung wäre pty, sich mit so etwas direkt mit a zu verbinden pexpect.