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ตัวมันเองกำลังบัฟเฟอร์เอาต์พุตดังนั้นคุณจะโชคไม่ดี
วิธีการแก้ปัญหาที่จะเชื่อมต่อโดยตรงกับการใช้สิ่งที่ต้องการptypexpect