subprocess
กฎระเบียบบางส่วนของหัวแม่มือสำหรับ
- ไม่เคย
shell=True
ใช้งาน โดยไม่จำเป็นต้องเรียกใช้กระบวนการเชลล์เพิ่มเติมเพื่อเรียกโปรแกรมของคุณ
- เมื่อเรียกกระบวนการอาร์กิวเมนต์จะถูกส่งผ่านเป็นรายการ
sys.argv
ใน python เป็นรายการและก็อยู่argv
ใน C ดังนั้นคุณจึงส่งผ่านรายการไปPopen
เพื่อเรียกกระบวนการย่อยไม่ใช่สตริง
- อย่าเปลี่ยนเส้นทาง
stderr
ไปยังข้อความPIPE
เมื่อคุณไม่ได้อ่าน
- อย่าเปลี่ยนเส้นทาง
stdin
เมื่อคุณไม่ได้เขียนถึงมัน
ตัวอย่าง:
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())
ที่กล่าวว่าเป็นไปได้ว่า rsync จะบัฟเฟอร์เอาต์พุตเมื่อตรวจพบว่าเชื่อมต่อกับท่อแทนที่จะเป็นเทอร์มินัล นี่คือลักษณะการทำงานเริ่มต้น - เมื่อเชื่อมต่อกับไพพ์โปรแกรมต่างๆต้องล้าง stdout อย่างชัดเจนเพื่อให้ได้ผลลัพธ์แบบเรียลไทม์มิฉะนั้นไลบรารี C มาตรฐานจะบัฟเฟอร์
หากต้องการทดสอบให้ลองรันสิ่งนี้แทน:
cmd = [sys.executable, 'test_out.py']
และสร้างtest_out.py
ไฟล์ที่มีเนื้อหา:
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
การดำเนินการตามกระบวนการย่อยนั้นควรให้คุณ "สวัสดี" และรอ 10 วินาทีก่อนที่จะให้ "World" หากสิ่งนี้เกิดขึ้นกับรหัส python ด้านบนและไม่เกิดขึ้นrsync
นั่นหมายความว่าrsync
ตัวมันเองกำลังบัฟเฟอร์เอาต์พุตดังนั้นคุณจะโชคไม่ดี
วิธีการแก้ปัญหาที่จะเชื่อมต่อโดยตรงกับการใช้สิ่งที่ต้องการpty
pexpect