Jawaban untuk pertanyaan ini tergantung pada versi Python yang Anda gunakan. Pendekatan paling sederhana adalah dengan menggunakan subprocess.check_outputfungsi:
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
check_outputmenjalankan 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 runatau Popen. Jika Anda ingin menjalankan perintah shell yang kompleks, lihat catatan shell=Truedi akhir jawaban ini.
The check_outputfungsi 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 subprocessmodul. Untuk menangkap hasil dari suatu program, berikan subprocess.PIPEtanda pada stdoutargumen kata kunci. Kemudian akses stdoutatribut dari CompletedProcessobjek 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 bytesobjek, 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 bytesobjek ke inputargumen 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.stdoutbersama dengan output reguler). Ketika keamanan tidak menjadi masalah, Anda juga dapat menjalankan perintah shell yang lebih kompleks dengan melewati shell=Trueseperti 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 runfungsi 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_outputfungsi 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_outputsetara dengan mengeksekusirun dengan check=Truedan stdout=PIPE, dan mengembalikan stdoutatribut saja.
Anda dapat melewati stderr=subprocess.STDOUTuntuk memastikan bahwa pesan kesalahan termasuk dalam output kembali - tetapi dalam beberapa versi Python lewat stderr=subprocess.PIPEuntuk check_outputdapat menyebabkan deadlock . Ketika keamanan tidak menjadi masalah, Anda juga dapat menjalankan perintah shell yang lebih kompleks dengan melewati shell=Trueseperti yang dijelaskan dalam catatan di bawah ini.
Jika Anda perlu pipa dari stderr mengirim atau mengirim input ke proses, check_outputtidak akan sesuai dengan tugas. Lihat Popencontoh 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_outputdisediakan, Anda harus bekerja secara langsung dengannyaPopen objek, yang merangkum API tingkat rendah untuk subproses.
The Popenkonstruktor 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.splitdapat membantu mem-parsing string ke dalam daftar yang diformat dengan tepat. Popenbenda juga menerima a sejumlah argumen yang berbeda untuk manajemen IO proses dan konfigurasi tingkat rendah.
Untuk mengirim input dan menangkap output, communicatehampir 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, communicatejuga 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, stderrdan stdinsemua 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 Popenkonstruktor 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_outputmengembalikan sebuah string dengan Python 2, tetapi sebuah bytesobjek dengan Python 3. Perlu mengambil waktu sejenak untuk belajar tentang unicode jika Anda belum melakukannya.