วิธีดำเนินการคำสั่ง bash ในสคริปต์ไพ ธ อน


คำตอบ:


17

คำตอบของ @ milne ทำงานได้ แต่subprocess.call()ให้ความคิดเห็นเล็กน้อย

ฉันชอบที่จะใช้subprocess.check_output()เพื่อให้คุณสามารถวิเคราะห์สิ่งที่พิมพ์ไปยัง stdout:

 import subprocess
 res = subprocess.check_output(["sudo", "apt", "update"])
 for line in res.splitlines():
     # process the output line by line

check_output ส่งข้อผิดพลาดเมื่อออกจากศูนย์โดยคำสั่งที่เรียกใช้

โปรดทราบว่าสิ่งนี้จะไม่เรียกใช้bashหรือเชลล์อื่นถ้าคุณไม่ได้ระบุshellอาร์กิวเมนต์คำหลักให้กับฟังก์ชั่น (เช่นเดียวกับที่เป็นจริงsubprocess.call()และคุณไม่ควรถ้าไม่จำเป็นเพราะมันจะทำให้เกิดอันตรายต่อความปลอดภัย) มันจะเรียก คำสั่ง

หากคุณพบว่าตัวเองทำมาก (แตกต่างกัน) สวดคำสั่งจากหลามคุณอาจต้องการที่จะดูที่plumbum เมื่อคุณสามารถทำให้ (IMO) อ่านได้มากขึ้น:

from plumbum.cmd import sudo, apt, echo, cut

res = sudo[apt["update"]]()
chain = echo["hello"] | cut["-c", "2-"]
chain()

มันแนะนำให้ใช้ ( os.popenหรือos.system) อดีต: res = os.popen('sudo apt update').read()? @Aththon
alper

1
@alper อ่าน 0324 python.org/dev/peps/pep-0324 ที่อธิบายเหตุผลในการทำsubprocessแม้ว่าos.systemและos.popenมีอยู่แล้ว PEPs ดังกล่าวไม่ได้รับการยอมรับเพียงเล็กน้อย หลายคนให้ความคิดมากกว่านี้กับคุณหรือฉัน และsubprocessได้รับการปรับปรุงตั้งแต่ปีพ. ศ. 2546 และอื่น ๆ ก็ยังอยู่ที่นั่นเพื่อความเข้ากันได้แบบย้อนหลัง ให้คุณเปลี่ยนos.systemหน้าสีแดงด้วยตนเองแล้ว: โมดูลย่อยจะให้บริการที่มีประสิทธิภาพยิ่งขึ้นสำหรับการวางไข่กระบวนการใหม่และรับผลลัพธ์ การใช้โมดูลนั้นจะดีกว่าการใช้ฟังก์ชั่นนี้
Anthon

1
@alper ใช่คุณทำได้ ดังที่ฉันระบุว่าเป็นอันตรายด้านความปลอดภัยที่อาจเกิดขึ้นดังนั้นฉันไม่รู้ว่าทำไมคุณจึงคิดว่าเป็นสิ่งที่แนะนำ และการกล่าวอ้างsudoจะยิ่งทำให้รุนแรงขึ้นเท่านั้น บางทีการใช้ python-apt เป็นทางออกที่ดีกว่า (ฉันไม่ได้มองด้วยตนเอง)
Anthon

1
@alper ในกรณีนี้ลองดูplumbumอย่างจริงจังมันก็คุ้มค่าที่จะเร่งความเร็วด้วย
Anthon

1
@alper หากคุณใช้ Python3 คุณต้องทำเช่นนั้นใน Python2 คุณไม่ต้องการ กรุณาอย่าใช้ความเห็นที่นี่เป็นระบบแชท หากคุณมีคำถามโพสต์ไว้เช่นนี้
Anthon

8

เป็นไปได้ที่คุณจะใช้ bash เป็นโปรแกรมโดยมีพารามิเตอร์ -c สำหรับดำเนินการคำสั่ง:

ตัวอย่าง:

bashCommand = "sudo apt update"
output = subprocess.check_output(['bash','-c', bashCommand])

7

subprocessโมดูลถูกออกแบบมาเพื่อทำสิ่งนี้:

import subprocess
subprocess.call(["sudo", "apt", "update"])

หากคุณต้องการให้สคริปต์ยุติหากคำสั่งล้มเหลวคุณอาจพิจารณาใช้check_call()แทนการแยกรหัสส่งคืนด้วยตัวคุณเอง:

subprocess.check_call(["sudo", "apt", "update"])

สิ่งนี้ทำให้ฉันย้อนกลับต่อไปนี้: Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer (ฉันใช้ yum ในขณะที่ฉันใช้ Fedora เป็นระบบปฏิบัติการหลัก)
Dremor

3
คุณลืมวงเล็บเหลี่ยม
Milind Dumbare

1
นอกจากนี้โปรดทราบว่าsubprocess.call()กำลังปิดกั้นในขณะที่subprocess.Popen()ไม่ได้ปิดกั้น ..
heemayl

คุณหมายถึงอะไรโดย "บล็อก" @heemayl
alper

2

นอกจากนี้คุณสามารถใช้ 'os.popen'

ตัวอย่าง:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

เอาท์พุท:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

0

ใช้โมดูลกระบวนการย่อย

import subprocess
command = 'sudo apt update'
subprocess.check_call(command.split())

ทำไมฉันถึงได้รับข้อผิดพลาดเมื่อฉันใช้มัน
aquagremlin

subprocess.check_call (["sudo", "apt", "update"])
aquagremlin

CalledProcessError Traceback (การโทรล่าสุดครั้งล่าสุด) <ipython-input-21-33ce645708e7> ใน <module> () ----> 1 subprocess.check_call (["sudo", "apt", "apt", "update"]) / usr / lib / python2.7 / subprocess.pyc ใน check_call (* popenargs, ** kwargs) 188 ถ้า cmd ไม่มี: 189 cmd = popenargs [0] -> 190 เพิ่ม CalledProcessError (retcode, cmd) 191 คืน 0 192 CalledProcessError: คำสั่ง '[' sudo ',' apt ',' update ']' แสดงสถานะทางออกที่ไม่เป็นศูนย์ 1
aquagremlin

ข้อผิดพลาดนี้จะเกิดขึ้นเมื่อฉันเรียกใช้ในสมุดบันทึก
jupyter

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