Subprocess di Python
Subprocess adalah proses independen yang berjalan bersamaan dengan proses utama program. Di Python, subprocess umumnya digunakan untuk mengeksekusi perintah atau skrip eksternal, berinteraksi dengan aplikasi lain, dan mengelola paralelisme dalam komputasi.
Modul subprocess
Modul subprocess, diperkenalkan di Python 2.4 dan ditingkatkan di Python 3, adalah cara yang direkomendasikan untuk mengelola subprocess di Python. Modul ini menyediakan antarmuka sederhana dan konsisten untuk membuat, berinteraksi dengan, dan mengendalikan subprocess. Artikel ini akan membimbing Anda melalui berbagai fungsi dan kelas yang disediakan oleh modul subprocess.
Menjalankan Perintah Eksternal
Fungsi run()
Fungsi run()
adalah cara paling sederhana untuk mengeksekusi perintah eksternal menggunakan modul subprocess. Fungsi ini mengambil daftar argumen baris perintah, menjalankan perintah yang ditentukan, dan menunggu hingga perintah selesai. Berikut adalah contohnya:command-line arguments, runs the specified command, and waits for it to complete. Here's an example:
import subprocess
result = subprocess.run(["echo", "Hello, World!"])
Argumen Perintah
Saat memasukkan argumen baris perintah ke dalam fungsi run()
, penting untuk memberikan setiap argumen sebagai item terpisah dalam daftar. Ini memastikan bahwa argumen dengan spasi ditangani dengan benar. Sebagai contoh:
import subprocess
# Incorrect: spaces in the file path will cause an error
result = subprocess.run(["ls", "/path/to directory with spaces"])
# Correct: each argument is a separate item in the list
result = subprocess.run(["ls", "/path/to", "directory with spaces"])
Mengatasi Kesalahan dan Pengecualian
Secara default, fungsi run()
akan menimbulkan pengecualian CalledProcessError
jika perintah mengembalikan status keluar non-zero. Untuk menangani situasi ini, Anda dapat menggunakan parameter check
:
import subprocess
try:
result = subprocess.run(["false"], check=True)
except subprocess.CalledProcessError as e:
print(f"The command failed with error: {e}")
Menangkap Output Perintah
Standar Output (stdout)
Untuk menangkap output standar (stdout) dari perintah, gunakan parameter capture_output
dengan fungsi run()
:
import subprocess
result = subprocess.run(["echo", "Hello, World!"], capture_output=True)
output = result.stdout.decode('utf-8')
print(output)
Standard Error (stderr)
Demikian pula, untuk menangkap standar error (stderr) dari perintah, atur parameter capture_output
ke True dan akses atribut stderr
dari objek yang dikembalikan:
import subprocess
result = subprocess.run(["command_that_may_fail"], capture_output=True)
error_output = result.stderr.decode('utf-8')
print(error_output)
Mengalihkan Output
Untuk mengalihkan keluaran perintah ke file, gunakan parameter stdout
dan stderr
dengan fungsi run()
:
import subprocess
with open("output.txt", "w") as output_file:
subprocess.run(["echo", "Hello, World!"], stdout=output_file)
Menggabungkan stdout dan stderr
Untuk menangkap kedua keluaran stdout dan stderr dalam satu keluaran, gunakan parameter stderr
dan atur ke subprocess.STDOUT
:
import subprocess
result = subprocess.run(["command_with_both_outputs"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
combined_output = result.stdout.decode('utf-8')
print(combined_output)
Manajemen Subproses Lanjutan
Kelas Popen
Kelas Popen
memberikan lebih banyak kontrol atas subproses dibandingkan dengan fungsi run()
. Dengan Popen
, Anda dapat berinteraksi dengan proses yang berjalan, mengirim data ke inputnya, dan membaca data dari keluarannya secara real-time. Berikut ini adalah contoh penggunaan Popen
untuk memulai perintah:
import subprocess
process = subprocess.Popen(["command", "arg1", "arg2"])
Atribut dan Metode Proses
Instance Popen
memiliki beberapa atribut dan metode untuk membantu Anda mengelola proses yang berjalan:
pid
: ID proses dari subproses yang berjalan.returncode
: Kode pengembalian proses, jika sudah selesai; jika tidak, maka None.wait()
: Tunggu proses sampai selesai dan kembalikan kode pengembalian.poll()
: Periksa apakah proses sudah selesai; jika ya, kembalikan kode pengembalian, jika tidak, kembalikan None.
import subprocess
process = subprocess.Popen(["command", "arg1", "arg2"])
process.wait()
print(f"Process return code: {process.returncode}")
Interaksi Proses
Dengan kelas Popen
, Anda dapat mengirim data ke input standar proses (stdin) dan membaca data dari output standar (stdout) dan error standar (stderr) proses. Untuk melakukannya, atur parameter stdin
, stdout
, dan stderr
ke subprocess.PIPE
:
import subprocess
process = subprocess.Popen(["command", "arg1", "arg2"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Send data to stdin
process.stdin.write(b"input data")
process.stdin.flush()
# Read data from stdout and stderr
output = process.stdout.read()
error_output = process.stderr.read()
# Close the input and wait for the process to finish
process.stdin.close()
process.wait()
Batas Waktu dan Penghentian Proses
Menetapkan Batas Waktu
Untuk menetapkan batas waktu untuk sebuah subproses, gunakan parameter timeout
dengan fungsi run()
atau metode wait()
dari instance Popen
:
import subprocess
try:
result = subprocess.run(["command", "arg1", "arg2"], timeout=5)
except subprocess.TimeoutExpired:
print("The command took too long to complete")
# Alternatively, with Popen
process = subprocess.Popen(["command", "arg1", "arg2"])
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
print("The command took too long to complete")
Menghentikan Proses
Untuk menghentikan subproses yang sedang berjalan, gunakan metode terminate()
dari instance Popen
:
import subprocess
process = subprocess.Popen(["command", "arg1", "arg2"])
process.terminate()
Berinteraksi dengan Proses
Metode communicate()
dari instance Popen
memungkinkan Anda untuk mengirim data ke stdin proses dan membaca data dari stdout dan stderr. Metode ini juga menunggu proses untuk selesai. Metode ini berguna ketika Anda perlu mengirim dan menerima data tanpa risiko terjadinya deadlock:
import subprocess
process = subprocess.Popen(["command", "arg1", "arg2"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error_output = process.communicate(input=b"input data")
print(f"Output: {output.decode('utf-8')}")
print(f"Error Output: {error_output.decode('utf-8')}")
Referensi