ฉันจะไพพ์การเรียกกระบวนการย่อยไปยังไฟล์ข้อความได้อย่างไร


97
subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"])

ตอนนี้ฉันมีสคริปต์ที่ฉันเรียกใช้ เมื่อฉันเรียกใช้และมันมาถึงบรรทัดนี้มันจะเริ่มพิมพ์สิ่งต่างๆเพราะ run.sh มีการพิมพ์อยู่ในนั้น

ฉันจะไพพ์สิ่งนี้ไปยังไฟล์ข้อความได้อย่างไร (และพิมพ์ด้วยถ้าเป็นไปได้)

คำตอบ:


179

หากคุณต้องการเขียนผลลัพธ์ลงในไฟล์คุณสามารถใช้stdout -argument ของsubprocess.call.

มันต้องใช้เวลาNone, subprocess.PIPEวัตถุไฟล์หรืออธิบายไฟล์ อันดับแรกคือค่าเริ่มต้น stdout จะสืบทอดมาจากพาเรนต์ (สคริปต์ของคุณ) อย่างที่สองให้คุณไพพ์จากคำสั่ง / กระบวนการหนึ่งไปยังอีกคำสั่งหนึ่ง อันที่สามและสี่คือสิ่งที่คุณต้องการเพื่อให้เอาต์พุตเขียนลงในไฟล์

คุณต้องเปิดไฟล์ที่มีบางอย่างเช่นopenและส่งอ็อบเจ็กต์หรือไฟล์ตัวอธิบายจำนวนเต็มไปที่call:

f = open("blah.txt", "w")
subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"], stdout=f)

ฉันเดาว่าวัตถุที่เหมือนไฟล์ที่ถูกต้องจะใช้งานได้เช่นซ็อกเก็ต (อ้าปากค้าง :)) แต่ฉันไม่เคยลอง

ในฐานะที่เป็นmarcogกล่าวถึงในความคิดเห็นที่คุณอาจต้องการที่จะเปลี่ยนเส้นทาง stderr เช่นกันคุณสามารถเปลี่ยนเส้นทางไปยังสถานที่นี้เช่นเดียวกับ stdout stderr=subprocess.STDOUTกับ ค่าใด ๆ ที่กล่าวถึงข้างต้นก็ใช้ได้เช่นกันคุณสามารถเปลี่ยนเส้นทางไปยังที่ต่างๆได้


6
ทำไม subprocess.call (["echo", "1", ">>", "t.txt"]) ไม่ทำงาน
StackOverflowOfficial

7
@Goldname คุณต้องมีเชลล์เพื่อทำการเปลี่ยนเส้นทางดังนั้นsubprocess.call(["echo", "1", ">>", "t.txt"], shell=True)ควรใช้งานได้
Wes Mason

@WesMason ขอบคุณ แต่ฉันคิดว่า subprocess.call ทำงานในลักษณะที่เหมือนกับการคัดลอกและวางลงในเชลล์โดยทั่วไป?
StackOverflowOfficial

2
@Goldname nah ทุกอย่างในกระบวนการย่อยขึ้นอยู่กับคลาส Popen พื้นฐานซึ่งเปิดกระบวนการ shell = True จะบังคับให้กระบวนการดำเนินการในเชลล์เริ่มต้นของระบบ (เช่น / bin / sh บนระบบ POSIX ซึ่งโดยปกติจะเป็น bash หรือ dash ) มันปลอดภัยกว่าด้วยวิธีนี้เนื่องจากคุณไม่ได้เปิดรับฟังก์ชั่นพิเศษทั้งหมดที่มีให้โดยเชลล์ (เป็นภาษาการเขียนโปรแกรมทั้งหมดสำหรับตัวมันเองโดยมีช่องโหว่ของตัวเองหากส่งผ่านข้อมูลที่ผู้ใช้ให้มา) ตรวจสอบshlex.quoteด้วยว่าคุณกำลังส่งข้อมูลสกปรกไปยัง subshell หรือไม่
Wes Mason

4
เราควรปิดไฟล์หลังจากทำเสร็จแล้วหรือยัง? สิ่งนี้จะปิดไฟล์หลังจากที่เราทำเสร็จแล้ว: with open("blah.txt","w") as f: subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml", "/tmp/video_xml"], stdout=f) @Skurmedel
alper

19

ตัวเลือกสำหรับpopenสามารถใช้ในcall

args, 
bufsize=0, 
executable=None, 
stdin=None, 
stdout=None, 
stderr=None, 
preexec_fn=None, 
close_fds=False, 
shell=False, 
cwd=None, 
env=None, 
universal_newlines=False, 
startupinfo=None, 
creationflags=0

ดังนั้น...

subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"], stdout=myoutput)

จากนั้นคุณสามารถทำสิ่งที่คุณต้องการด้วยmyoutput(ซึ่งจะต้องเป็นไฟล์ btw)

นอกจากนี้คุณสามารถทำบางสิ่งที่ใกล้เคียงกับเอาต์พุตแบบ piped เช่นนี้

dmesg | grep hda

อยากจะเป็น:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

มีมากมายของน่ารักข้อมูลที่เป็นประโยชน์เกี่ยวกับการเป็นคู่มือหลามหน้า


-2

คุณยังสามารถเรียกใช้สคริปต์จากเทอร์มินัลโดยส่งออกทุกอย่างไปยังไฟล์ได้หากช่วยได้ ทางนี้:

$ /path/to/the/script.py > output.txt

สิ่งนี้จะเขียนทับไฟล์ คุณสามารถใช้>>เพื่อต่อท้ายได้

หากคุณต้องการให้บันทึกข้อผิดพลาดในไฟล์ด้วยให้ใช้&>>หรือ&>.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.