Saya perlu menjalankan perintah shell secara asinkron dari skrip Python. Maksud saya, saya ingin skrip Python saya terus berjalan saat perintah eksternal mati dan melakukan apa pun yang perlu dilakukan.
Saya membaca posting ini:
Saya kemudian pergi dan melakukan beberapa pengujian, dan sepertinya os.system()
akan melakukan pekerjaan asalkan saya gunakan &
di akhir perintah sehingga saya tidak perlu menunggu untuk kembali. Yang saya pikirkan adalah apakah ini cara yang tepat untuk mencapai hal seperti itu? Saya mencoba commands.call()
tetapi tidak akan berhasil untuk saya karena blok pada perintah eksternal.
Tolong beri tahu saya jika menggunakan os.system()
untuk ini disarankan atau jika saya harus mencoba beberapa rute lain.
sumber
Jika Anda ingin menjalankan banyak proses secara paralel dan kemudian menanganinya saat mereka membuahkan hasil, Anda dapat menggunakan polling seperti berikut:
Aliran kontrol di sana sedikit berbelit-belit karena saya mencoba membuatnya kecil - Anda dapat menyesuaikan dengan selera Anda. :-)
Ini memiliki keuntungan dalam melayani permintaan penyelesaian awal terlebih dahulu. Jika Anda memanggil
communicate
proses yang berjalan pertama dan ternyata berjalan paling lama, proses yang berjalan lainnya akan diam di sana saat Anda seharusnya menangani hasilnya.sumber
os.waitpid
secara langsung yang memungkinkan untuk memeriksa apakah ada proses anak yang telah mengubah statusnya.['/usr/bin/my_cmd', '-i', path]
sebagai pengganti['/usr/bin/my_cmd', '-i %s' % path]
Apa yang saya ingin tahu adalah apakah [os.system ()] ini adalah cara yang tepat untuk mencapai hal seperti itu?
Tidak,
os.system()
bukanlah cara yang tepat. Itulah mengapa semua orang mengatakan untuk menggunakansubprocess
.Untuk informasi lebih lanjut, baca http://docs.python.org/library/os.html#os.system
sumber
Saya telah berhasil dengan baik dengan modul asyncproc , yang berhubungan dengan baik dengan keluaran dari proses. Sebagai contoh:
sumber
Menggunakan pexpect dengan garis baca non-pemblokiran adalah cara lain untuk melakukan ini. Pexpect memecahkan masalah kebuntuan, memungkinkan Anda menjalankan proses dengan mudah di latar belakang, dan memberikan cara mudah untuk memiliki callback saat proses Anda mengeluarkan string yang telah ditentukan, dan umumnya membuat interaksi dengan proses menjadi lebih mudah.
sumber
Mempertimbangkan "Saya tidak perlu menunggu sampai kembali", salah satu solusi termudah adalah ini:
Tapi ... Dari apa yang saya baca ini bukanlah "cara yang tepat untuk mencapai hal seperti itu" karena risiko keamanan yang ditimbulkan
subprocess.CREATE_NEW_CONSOLE
bendera.Hal-hal utama yang terjadi di sini adalah penggunaan
subprocess.CREATE_NEW_CONSOLE
untuk membuat konsol baru dan.pid
(mengembalikan ID proses sehingga Anda dapat memeriksa program nanti jika Anda mau) sehingga tidak menunggu program menyelesaikan tugasnya.sumber
Saya memiliki masalah yang sama saat mencoba menyambung ke terminal 3270 menggunakan perangkat lunak scripting s3270 dengan Python. Sekarang saya sedang memecahkan masalah dengan subkelas Proses yang saya temukan di sini:
http://code.activestate.com/recipes/440554/
Dan berikut ini contoh yang diambil dari file:
sumber
Jawaban yang diterima sudah sangat tua.
Saya menemukan jawaban modern yang lebih baik di sini:
https://kevinmccarthy.org/2016/07/25/streaming-subprocess-stdin-and-stdout-with-asyncio-in-python/
dan membuat beberapa perubahan:
Tidak mungkin bahwa contoh perintah akan bekerja dengan sempurna di sistem Anda, dan tidak menangani kesalahan aneh, tetapi kode ini menunjukkan satu cara untuk menjalankan beberapa subproses menggunakan asyncio dan mengalirkan output.
sumber
wait()
secara langsung tidak digunakan lagiAda beberapa jawaban di sini tetapi tidak ada yang memenuhi persyaratan saya di bawah ini:
Saya tidak ingin menunggu perintah selesai atau mencemari terminal saya dengan keluaran subproses.
Saya ingin menjalankan skrip bash dengan pengalihan.
Saya ingin mendukung perpipaan dalam skrip bash saya (misalnya
find ... | tar ...
).Satu-satunya kombinasi yang memenuhi persyaratan di atas adalah:
sumber
Ini dicakup oleh Contoh Subproses Python 3 di bawah "Tunggu perintah untuk berhenti secara asinkron":
Prosesnya akan mulai berjalan segera setelah
await asyncio.create_subprocess_exec(...)
selesai. Jika belum selesai pada saat Anda meneleponawait proc.communicate()
, itu akan menunggu di sana untuk memberi Anda status keluaran. Jika sudah selesai,proc.communicate()
akan langsung dikembalikan.Intinya di sini mirip dengan jawaban Terrels tetapi saya pikir jawaban Terrels tampaknya terlalu rumit.
Lihat
asyncio.create_subprocess_exec
untuk informasi lebih lanjut.sumber