Próbuję napisać skrypt opakowujący dla programu wiersza poleceń (weryfikacja svnadmin), który będzie wyświetlał ładny wskaźnik postępu operacji. Wymaga to ode mnie możliwości zobaczenia każdego wiersza wyjścia z opakowanego programu, gdy tylko zostanie on wyprowadzony.
Pomyślałem, że po prostu uruchomię program za pomocą subprocess.Popen
, użyję stdout=PIPE
, a następnie przeczytam każdą linię, gdy się pojawi i odpowiednio z nią postąpię. Jednak gdy uruchomiłem następujący kod, dane wyjściowe wydawały się być gdzieś buforowane, powodując, że pojawiały się w dwóch fragmentach, wierszach od 1 do 332, a następnie od 333 do 439 (ostatnia linia danych wyjściowych)
from subprocess import Popen, PIPE, STDOUT
p = Popen('svnadmin verify /var/svn/repos/config', stdout = PIPE,
stderr = STDOUT, shell = True)
for line in p.stdout:
print line.replace('\n', '')
Po przyjrzeniu się nieco dokumentacji podprocesu odkryłem, że bufsize
parametr to Popen
, więc próbowałem ustawić rozmiar bufora na 1 (bufor każdej linii) i 0 (brak bufora), ale żadna z wartości nie wydawała się zmieniać sposobu dostarczania linii.
W tym momencie zacząłem sięgać po słomki, więc napisałem następującą pętlę wyjściową:
while True:
try:
print p.stdout.next().replace('\n', '')
except StopIteration:
break
ale uzyskał ten sam wynik.
Czy możliwe jest uzyskanie danych wyjściowych programu w czasie rzeczywistym programu wykonanego przy użyciu podprocesu? Czy jest jakaś inna opcja w Pythonie, która jest kompatybilna z przyszłością (nie exec*
)?
sydout=PIPE
więc podproces zapisuje bezpośrednio na konsoli, pomijając proces nadrzędny?