คำตอบอื่น ๆ ที่นี่อย่างเพียงพออธิบายคำเตือนความปลอดภัยที่กล่าวถึงใน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
ในกรณีส่วนใหญ่แทนที่จะเป็นรายการ