Bazı pratik kurallar subprocess.
- Asla kullanma
shell=True. Programınızı çağırmak için gereksiz yere fazladan bir kabuk işlemi başlatır.
- Süreçleri çağırırken, argümanlar liste olarak iletilir.
sys.argvPython'da bir listedir ve argvC'de de böyledir . Yani alt süreçleri çağırmak için bir liste iletirsiniz Popen, dizge değil.
- Yönlendirmeyin
stderra PIPEbunu okurken değilken.
- Yazmadığınız
stdinzamanlarda yeniden yönlendirmeyin .
Misal:
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())
Bununla birlikte, rsync'in bir terminal yerine bir boruya bağlı olduğunu algıladığında çıktısını tamponlaması muhtemeldir. Bu varsayılan davranıştır - bir boruya bağlandığında, programlar gerçek zamanlı sonuçlar için stdout'u açıkça yıkamalıdır, aksi takdirde standart C kitaplığı arabelleğe alınır.
Bunu test etmek için bunun yerine şunu çalıştırmayı deneyin:
cmd = [sys.executable, 'test_out.py']
ve test_out.pyiçeriğe sahip bir dosya oluşturun :
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
Bu alt işlemi yürütmek size "Merhaba" vermeli ve "Dünya" vermeden önce 10 saniye beklemelidir. Bu, yukarıdaki python koduyla gerçekleşirse ve bununla birlikte olmazsa rsync, bu rsync, çıktının arabelleğe alındığı anlamına gelir , yani şansınız kalmaz .
Bir çözüm pty, gibi bir şey kullanarak doğrudan a'ya bağlanmak olabilir pexpect.