Làm thế nào để thực thi lệnh bash trong tập lệnh python


Câu trả lời:


15

Câu trả lời của @ milne hoạt động, nhưng subprocess.call()cung cấp cho bạn ít phản hồi.

Tôi thích sử dụng subprocess.check_output()để bạn có thể phân tích những gì đã được in ra thiết bị xuất chuẩn:

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

check_output đưa ra một lỗi trên lối thoát bằng không của lệnh được gọi

Xin lưu ý rằng điều này không gọi bashhoặc shell khác nếu bạn không chỉ định shellđối số từ khóa cho hàm (điều này cũng đúng subprocess.call()và bạn không nên nếu không cần thiết vì nó gây nguy hiểm bảo mật), nó trực tiếp gọi chỉ huy.

Nếu bạn thấy mình đang thực hiện rất nhiều lệnh (khác nhau) từ Python, bạn có thể muốn xem xét plumbum . Với điều đó, bạn có thể làm (IMO) dễ đọc hơn:

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

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

Có nên sử dụng ( os.popenhoặc os.system), ví dụ : res = os.popen('sudo apt update').read()? @Anthon
ngày

1
@alper Đọc 0324 python.org/dev/peps/pep-0324 . Điều đó giải thích lý do để thực hiện subprocessmặc dù os.systemos.popenđã tồn tại. PEP như vậy là không tầm thường để được chấp nhận. Một số người đã suy nghĩ nhiều về điều đó hơn bạn hoặc tôi sẽ làm. Và subprocessđã được cải thiện từ năm 2003, những cái khác vẫn còn đó để tương thích ngược. Bạn có tô đỏ os.systemtrang thủ công: Mô-đun quy trình con cung cấp các phương tiện mạnh hơn để sinh ra các quy trình mới và lấy kết quả của chúng; sử dụng mô-đun đó là tốt hơn để sử dụng chức năng này.
Anthon

1
@alper Có bạn có thể. Như tôi đã chỉ ra rằng đó là một mối nguy hiểm an ninh tiềm tàng, vì vậy tôi không biết tại sao bạn nghĩ rằng điều đó được khuyến nghị. Và viện dẫn sudosẽ chỉ làm cho điều đó nghiêm trọng hơn. Có lẽ sử dụng python-apt là một giải pháp tốt hơn (bản thân tôi chưa xem xét điều đó).
Anthon

1
@alper trong trường hợp đó hãy xem xét nghiêm túc về plumbum , đáng để bắt kịp với tốc độ đó.
Anthon

1
@alper Nếu bạn đang dùng Python3, bạn cần phải làm điều đó, trên Python2 thì không. Vui lòng không sử dụng nhận xét ở đây như một hệ thống trò chuyện. Nếu bạn có một câu hỏi gửi nó như vậy.
Anthon

8

Có thể bạn sử dụng bash như một chương trình, với tham số -c để thực thi các lệnh:

Thí dụ:

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

6

Các tiến trình con mô-đun được thiết kế để làm việc này:

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

Nếu bạn muốn tập lệnh chấm dứt nếu lệnh thất bại, bạn có thể cân nhắc sử dụng check_call()thay vì tự phân tích mã trả về:

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

điều này mang lại cho tôi sự truy nguyên sau: 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 (Tôi đang sử dụng yum vì tôi đang sử dụng Fedora làm hệ điều hành chính)
Dremor

3
Bạn đã quên dấu ngoặc vuông
Milind Dumbare

1
Cũng lưu ý rằng subprocess.call()việc chặn trong khi subprocess.Popen()không chặn ..
heemayl

Bạn có ý nghĩa gì khi "chặn"? @heemayl
alper

2

Ngoài ra, bạn có thể sử dụng 'os.popen'.

Thí dụ:

import os

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

Đầu ra:

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

sử dụng mô đun quy trình con

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

tại sao tôi gặp lỗi khi tôi sử dụng nó
aquagremlin


CalledProcessError TracBack (cuộc gọi gần đây nhất) <ipython-input-21-33ce645708e7> trong <module> () ----> 1 sub process.check_call (["sudo", "apt", "update"]) / usr / lib / python2.7 / sub process.pyc in check_call (* popenargs, ** kwargs) 188 nếu cmd là Không có: 189 cmd = popenargs [0] -> 190 nâng CalledProcessError (retcode, cmd) 191 return 0 192 CalledProcessEr '[' sudo ',' apt ',' update ']' đã trả về trạng thái thoát khác không 1
aquagremlin

lỗi này chỉ xảy ra khi tôi chạy nó trong máy tính xách tay
jupyter

có lẽ tôi sẽ bắt đầu một câu hỏi mới vì đây là ot
aquagremlin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.