Jawaban untuk pertanyaan ini tergantung pada versi Python yang Anda gunakan. Pendekatan paling sederhana adalah dengan menggunakan subprocess.check_output
fungsi:
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
check_output
menjalankan satu program yang hanya menggunakan argumen sebagai input. 1 Ini mengembalikan hasil persis seperti yang dicetak stdout
. Jika Anda perlu menulis input stdin
, lanjutkan ke bagian run
atau Popen
. Jika Anda ingin menjalankan perintah shell yang kompleks, lihat catatan shell=True
di akhir jawaban ini.
The check_output
fungsi bekerja pada hampir semua versi Python masih digunakan secara luas (2.7+). 2 Tetapi untuk versi yang lebih baru, ini bukan lagi pendekatan yang direkomendasikan.
Versi modern Python (3.5 atau lebih tinggi): run
Jika Anda menggunakan Python 3.5 atau lebih tinggi, dan tidak perlu kompatibilitas ke belakang , fungsi barurun
disarankan. Ini menyediakan API tingkat tinggi yang sangat umum untuk subprocess
modul. Untuk menangkap hasil dari suatu program, berikan subprocess.PIPE
tanda pada stdout
argumen kata kunci. Kemudian akses stdout
atribut dari CompletedProcess
objek yang dikembalikan :
>>> import subprocess
>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Nilai kembali adalah bytes
objek, jadi jika Anda menginginkan string yang tepat, Anda harus melakukannya decode
. Dengan asumsi proses yang dipanggil mengembalikan string yang dikodekan UTF-8:
>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Ini semua dapat dikompresi menjadi satu-liner:
>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
Jika Anda ingin meneruskan input ke proses stdin
, berikan bytes
objek ke input
argumen kata kunci:
>>> cmd = ['awk', 'length($0) > 5']
>>> input = 'foo\nfoofoo\n'.encode('utf-8')
>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=input)
>>> result.stdout.decode('utf-8')
'foofoo\n'
Anda dapat menangkap kesalahan dengan meneruskan stderr=subprocess.PIPE
(capture to result.stderr
) atau stderr=subprocess.STDOUT
(capture to result.stdout
bersama dengan output reguler). Ketika keamanan tidak menjadi masalah, Anda juga dapat menjalankan perintah shell yang lebih kompleks dengan melewati shell=True
seperti yang dijelaskan dalam catatan di bawah ini.
Ini menambah sedikit kompleksitas, dibandingkan dengan cara lama dalam melakukan sesuatu. Tetapi saya pikir ini sepadan dengan hasilnya: sekarang Anda dapat melakukan hampir semua hal yang perlu Anda lakukan dengan run
fungsi itu saja.
Versi Python yang lebih lama (2.7-3.4): check_output
Jika Anda menggunakan versi Python yang lebih lama, atau membutuhkan kompatibilitas mundur sederhana, Anda mungkin dapat menggunakan check_output
fungsi seperti dijelaskan secara singkat di atas. Ini telah tersedia sejak Python 2.7.
subprocess.check_output(*popenargs, **kwargs)
Dibutuhkan argumen yang sama seperti Popen
(lihat di bawah), dan mengembalikan string yang berisi keluaran program. Awal dari jawaban ini memiliki contoh penggunaan yang lebih rinci. Dalam Python 3.5 dan lebih tinggi, check_output
setara dengan mengeksekusirun
dengan check=True
dan stdout=PIPE
, dan mengembalikan stdout
atribut saja.
Anda dapat melewati stderr=subprocess.STDOUT
untuk memastikan bahwa pesan kesalahan termasuk dalam output kembali - tetapi dalam beberapa versi Python lewat stderr=subprocess.PIPE
untuk check_output
dapat menyebabkan deadlock . Ketika keamanan tidak menjadi masalah, Anda juga dapat menjalankan perintah shell yang lebih kompleks dengan melewati shell=True
seperti yang dijelaskan dalam catatan di bawah ini.
Jika Anda perlu pipa dari stderr
mengirim atau mengirim input ke proses, check_output
tidak akan sesuai dengan tugas. Lihat Popen
contoh di bawah ini dalam kasus itu.
Aplikasi kompleks & versi lama Python (2.6 dan di bawah): Popen
Jika Anda memerlukan kompatibilitas mundur yang dalam, atau jika Anda membutuhkan fungsionalitas yang lebih canggih daripada yang check_output
disediakan, Anda harus bekerja secara langsung dengannyaPopen
objek, yang merangkum API tingkat rendah untuk subproses.
The Popen
konstruktor menerima baik perintah tunggal tanpa argumen, atau daftar yang berisi perintah sebagai pos pertama, diikuti oleh sejumlah argumen, masing-masing sebagai bagian yang terpisah dalam daftar. shlex.split
dapat membantu mem-parsing string ke dalam daftar yang diformat dengan tepat. Popen
benda juga menerima a sejumlah argumen yang berbeda untuk manajemen IO proses dan konfigurasi tingkat rendah.
Untuk mengirim input dan menangkap output, communicate
hampir selalu metode yang disukai. Seperti dalam:
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
Atau
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
Jika Anda mengatur stdin=PIPE
, communicate
juga memungkinkan Anda untuk mengirimkan data ke proses melalui stdin
:
>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo\nfoofoo\n')
>>> print out
foofoo
Catatan Aaron Hall jawaban , yang menunjukkan bahwa pada beberapa sistem, Anda mungkin perlu set stdout
, stderr
dan stdin
semua untuk PIPE
(atau DEVNULL
) untuk mendapatkancommunicate
pekerjaan sama sekali.
Dalam beberapa kasus yang jarang terjadi, Anda mungkin perlu menangkap keluaran real-time yang kompleks. Jawaban Vartec menunjukkan jalan ke depan, tetapi metode selaincommunicate
rentan terhadap kebuntuan jika tidak digunakan dengan hati-hati.
Seperti semua fungsi di atas, ketika keamanan tidak menjadi perhatian, Anda dapat menjalankan perintah shell yang lebih kompleks dengan melewati shell=True
.
Catatan
1. Menjalankan perintah shell: the shell=True
argumen
Biasanya, setiap panggilan ke run
, check_output
, atau Popen
konstruktor mengeksekusi program tunggal . Itu berarti tidak ada pipa bergaya bash mewah. Jika Anda ingin menjalankan perintah shell yang kompleks, Anda bisa meneruskannyashell=True
, yang didukung oleh ketiga fungsi.
Namun, hal itu menimbulkan masalah keamanan . Jika Anda melakukan sesuatu lebih dari skrip ringan, Anda mungkin lebih baik memanggil setiap proses secara terpisah, dan meneruskan output dari masing-masing sebagai input ke yang berikutnya, melalui
run(cmd, [stdout=etc...], input=other_output)
Atau
Popen(cmd, [stdout=etc...]).communicate(other_output)
Godaan untuk menghubungkan langsung pipa kuat; menolaknya. Kalau tidak, Anda mungkin akan melihat kebuntuan atau harus melakukan hal-hal seperti ini .
2. Pertimbangan Unicode
check_output
mengembalikan sebuah string dengan Python 2, tetapi sebuah bytes
objek dengan Python 3. Perlu mengambil waktu sejenak untuk belajar tentang unicode jika Anda belum melakukannya.