cara menjalankan perintah bash dalam skrip python


Jawaban:


16

Jawaban @ milne bekerja, tetapi subprocess.call()memberi Anda sedikit umpan balik.

Saya lebih suka menggunakan subprocess.check_output()sehingga Anda dapat menganalisis apa yang dicetak ke stdout:

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

check_output melempar kesalahan saat keluar dari nol dari perintah yang dipanggil

Harap perhatikan bahwa ini tidak meminta bashatau shell lain jika Anda tidak menentukan shellargumen kata kunci untuk fungsi (hal yang sama berlaku untuk subprocess.call(), dan Anda tidak boleh jika tidak perlu karena menimbulkan bahaya keamanan), itu langsung memanggil perintah.

Jika Anda menemukan diri Anda melakukan banyak pemanggilan perintah (berbeda) dari Python, Anda mungkin ingin melihat timah hitam . Dengan itu Anda dapat melakukan (IMO) lebih mudah dibaca:

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

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

Apakah disarankan untuk menggunakan ( os.popenatau os.system), ex: res = os.popen('sudo apt update').read()? @Anthon
alper

1
@alper Baca 0324 python.org/dev/peps/pep-0324 . Itu menjelaskan alasan untuk membuat subprocessmeskipun os.systemdan os.popensudah ada. PEP semacam itu tidak mudah untuk diterima. Beberapa orang lebih memikirkan hal itu daripada Anda atau saya akan pernah. Dan subprocesstelah meningkat sejak tahun 2003, yang lainnya masih ada untuk kompatibilitas. Sudahkah Anda merah os.systemhalaman manual: Modul subproses menyediakan fasilitas yang lebih kuat untuk menelurkan proses baru dan mengambil hasilnya; menggunakan modul itu lebih baik daripada menggunakan fungsi ini.
Anthon

1
@ alper Ya Anda bisa. Seperti yang saya sebutkan itu adalah potensi bahaya keamanan, jadi saya tidak tahu mengapa Anda berpikir itu direkomendasikan. Dan memohon sudohanya akan membuat itu lebih parah. Mungkin menggunakan python-apt adalah solusi yang lebih baik (saya belum melihatnya sendiri).
Anthon

1
@alper dalam hal itu perhatikan dengan seksama pada timbal , ada baiknya untuk mempercepat dengan itu.
Anthon

1
@ alper Jika Anda menggunakan Python3, Anda perlu melakukannya, di Python2 tidak. Tolong jangan gunakan komentar di sini sebagai sistem obrolan. Jika Anda memiliki pertanyaan, poskan seperti itu.
Anthon

8

Mungkin Anda menggunakan bash sebagai program, dengan parameter -c untuk menjalankan perintah:

Contoh:

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

7

The subproses modul dirancang untuk melakukan hal ini:

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

Jika Anda ingin skrip untuk dihentikan jika perintah gagal, Anda dapat mempertimbangkan untuk menggunakan sendiri check_call()daripada menguraikan kode kembali:

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

ini memberi saya traceback berikut: 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 (Saya menggunakan yum karena saya menggunakan Fedora sebagai OS utama)
Dremor

3
Anda lupa tanda kurung
Milind Dumbare

1
Perhatikan juga bahwa subprocess.call()memblokir sementara subprocess.Popen()tidak memblokir ..
heemayl

Apa yang Anda maksud dengan "memblokir"? @heemayl
alper

2

Anda juga dapat menggunakan 'os.popen'.

Contoh:

import os

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

Keluaran:

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

gunakan modul subproses

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

mengapa saya mendapatkan pesan kesalahan ketika saya menggunakannya
aquagremlin

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

CalledProcessError Traceback (panggilan terakhir terakhir) <ipython-input-21-33ce645708e7> dalam <module> () ----> 1 subprocess.check_call (["sudo", "apt", "update"]) / usr / lib / python2.7 / subprocess.pyc di check_call (* popenargs, ** kwargs) 188 jika cmd Tidak ada: 189 cmd = popenargs [0] -> 190 meningkatkan CalledProcessError (retcode, cmd) 191 return 0 192 CalledProcess: Command '[' sudo ',' apt ',' update ']' mengembalikan status keluar tidak nol 1
aquagremlin

kesalahan ini hanya terjadi ketika saya menjalankannya di notebook
jupyter

mungkin saya akan memulai pertanyaan baru karena ini bukan
aquagremlin
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.