Beberapa aturan praktis untuk subprocess
.
- Jangan pernah gunakan
shell=True
. Itu tidak perlu memanggil proses shell ekstra untuk memanggil program Anda.
- Saat memanggil proses, argumen diteruskan sebagai daftar.
sys.argv
di python adalah daftar, dan begitu juga argv
di C. Jadi Anda lulus daftar untuk Popen
memanggil subproses, bukan string.
- Jangan mengalihkan
stderr
ke PIPE
saat Anda tidak membacanya.
- Jangan mengalihkan
stdin
ketika Anda tidak sedang menulis untuk itu.
Contoh:
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())
Meskipun demikian, kemungkinan besar rsync menyangga keluarannya ketika ia mendeteksi bahwa ia terhubung ke pipa dan bukan ke terminal. Ini adalah perilaku default - ketika terhubung ke pipa, program harus secara eksplisit membersihkan stdout untuk hasil realtime, jika tidak, library C standar akan buffer.
Untuk mengujinya, coba jalankan ini sebagai gantinya:
cmd = [sys.executable, 'test_out.py']
dan buat test_out.py
file dengan isinya:
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
Menjalankan subproses itu akan memberi Anda "Halo" dan menunggu 10 detik sebelum memberikan "Dunia". Jika itu terjadi dengan kode python di atas dan bukan dengan rsync
, itu berarti rsync
output buffering, jadi Anda kurang beruntung.
Solusinya adalah menghubungkan langsung ke pty
, menggunakan sesuatu seperti pexpect
.