คำตอบอื่น ๆ ที่นี่อย่างเพียงพออธิบายคำเตือนความปลอดภัยที่กล่าวถึงในsubprocessเอกสารประกอบ แต่นอกเหนือจากนั้นค่าใช้จ่ายในการเริ่มเชลล์เพื่อเริ่มโปรแกรมที่คุณต้องการเรียกใช้มักไม่จำเป็นและโง่มากสำหรับสถานการณ์ที่คุณไม่ได้ใช้ฟังก์ชั่นของเชลล์จริงๆ ยิ่งกว่านั้นความซับซ้อนที่ซ่อนอยู่เพิ่มเติมจะทำให้คุณกลัวโดยเฉพาะหากคุณไม่คุ้นเคยกับเชลล์หรือบริการที่ให้
ในกรณีที่การโต้ตอบกับเชลล์นั้นไม่ใช่เรื่องสำคัญตอนนี้คุณต้องมีผู้อ่านและผู้ดูแลของสคริปต์ Python (ซึ่งอาจเป็นหรืออาจไม่ใช่ตัวคุณเองในอนาคต) เพื่อทำความเข้าใจทั้ง Python และเชลล์สคริปต์ โปรดจำไว้ว่าคำขวัญ Python "ชัดเจนดีกว่าโดยนัย"; แม้ว่ารหัส Python จะค่อนข้างซับซ้อนกว่าเชลล์สคริปต์ที่เทียบเท่ากัน (และบ่อยครั้งมาก) คุณอาจจะดีกว่าที่จะลบเชลล์และแทนที่ฟังก์ชันด้วยการสร้าง Python ดั้งเดิม การลดงานที่ทำในกระบวนการภายนอกและควบคุมรหัสของคุณให้ไกลที่สุดมักเป็นความคิดที่ดีเพราะช่วยปรับปรุงการมองเห็นและลดความเสี่ยงของผลข้างเคียงที่ต้องการหรือไม่พึงประสงค์
การขยายสัญลักษณ์การแก้ไขตัวแปรและการเปลี่ยนเส้นทางทั้งหมดนั้นง่ายต่อการแทนที่ด้วยโครงสร้าง Python ดั้งเดิม ไพพ์ไลน์เชลล์ที่ซับซ้อนที่บางส่วนหรือทั้งหมดไม่สามารถเขียนใหม่ได้อย่างสมเหตุสมผลใน Python จะเป็นสถานการณ์หนึ่งที่บางทีคุณอาจพิจารณาใช้เชลล์ คุณควรตรวจสอบให้แน่ใจว่าคุณเข้าใจถึงประสิทธิภาพและความปลอดภัย
ในกรณีที่เล็กน้อยเพื่อหลีกเลี่ยงshell=Trueเพียงแทนที่
subprocess.Popen("command -with -options 'like this' and\\ an\\ argument", shell=True)
กับ
subprocess.Popen(['command', '-with','-options', 'like this', 'and an argument'])
ขอให้สังเกตว่าอาร์กิวเมนต์แรกคือรายการของสตริงที่จะส่งผ่านexecvp()และวิธีการอ้างถึงสตริงและอักขระเมตาอักขระเปลือก backslash-escaping โดยทั่วไปไม่จำเป็น (หรือมีประโยชน์หรือถูกต้อง) อาจจะเห็นคำสั่งล้อมรอบตัวแปรเชลล์เมื่อใด
นอกจากนี้คุณมักจะต้องการหลีกเลี่ยงPopenหากหนึ่งในสิ่งห่อหุ้มที่ง่ายกว่าในsubprocessแพ็คเกจทำสิ่งที่คุณต้องการ subprocess.runหากคุณมีมากพอที่ล่าสุดหลามคุณอาจจะใช้
- ด้วย
check=Trueมันจะล้มเหลวหากคำสั่งของคุณล้มเหลว
- ด้วย
stdout=subprocess.PIPEมันจะจับเอาท์พุทของคำสั่ง
- ค่อนข้างจะคลุมเครือ
universal_newlines=Trueเพราะมันจะถอดรหัสเอาท์พุทเป็น Unicode string ที่เหมาะสม (เป็นเพียงbytesการเข้ารหัสระบบมิฉะนั้นบน Python 3)
หากไม่ใช่สำหรับหลาย ๆ งานคุณต้องการcheck_outputรับเอาท์พุทจากคำสั่งขณะตรวจสอบว่ามันสำเร็จหรือcheck_callไม่มีการรวบรวมผลลัพธ์
ฉันจะปิดด้วยคำพูดจาก David Korn: "มันง่ายกว่าที่จะเขียนเชลล์แบบพกพาได้ง่ายกว่าสคริปเชลล์แบบพกพา" แม้subprocess.run('echo "$HOME"', shell=True)จะไม่พกพาไปที่ Windows
-lถูกส่งผ่านไป/bin/sh(เปลือก) แทนlsโปรแกรมบน Unixshell=Trueถ้า ควรใช้อาร์กิวเมนต์สตริงกับshell=Trueในกรณีส่วนใหญ่แทนที่จะเป็นรายการ