Saya mencoba untuk mem-porting skrip shell ke versi python yang lebih mudah dibaca. Skrip shell asli memulai beberapa proses (utilitas, monitor, dll.) Di latar belakang dengan "&". Bagaimana saya bisa mencapai efek yang sama dengan python? Saya ingin proses ini tidak mati ketika skrip python selesai. Saya yakin ini terkait dengan konsep daemon, tapi saya tidak bisa menemukan cara melakukan ini dengan mudah.
295
subprocess.Popen()
adalah cara yang disarankan baru sejak 2010 (kami berada di 2015 sekarang) dan (3) pertanyaan duplikat yang mengarahkan di sini juga memiliki jawaban yang diterima tentangsubprocess.Popen()
. Cheers :-)subprocess.Popen("<command>")
dengan file <command> yang dipimpin oleh shebang yang cocok. Bekerja sempurna untuk saya (Debian) dengan skrip bash dan python, secara implisitshell
s dan bertahan dari proses induknya.stdout
pergi ke terminal yang sama dari orang tua. Jadi ini berfungsi seperti&
dalam shell yang merupakan permintaan OPs. Tapi sih, semua pertanyaan berjalan sangat kompleks sementara pengujian kecil menunjukkannya dalam waktu singkat;)Jawaban:
Catatan : Jawaban ini kurang terkini daripada saat diposting pada tahun 2009. Menggunakan
subprocess
modul yang ditunjukkan dalam jawaban lain sekarang direkomendasikan dalam dokumenJika Anda ingin proses Anda dimulai di latar belakang, Anda dapat menggunakan
system()
dan memanggilnya dengan cara yang sama dengan skrip shell Anda, atau Anda dapatspawn
melakukannya:(Atau, sebagai alternatif, Anda dapat mencoba
os.P_NOWAIT
bendera yang kurang portabel ).Lihat dokumentasi di sini .
sumber
subprocess
memberi kita petunjuk bagaimana melepaskan suatu prosessubprocess
?Sementara solusi jkp bekerja, cara yang lebih baru dalam melakukan sesuatu (dan cara dokumentasi merekomendasikan) adalah dengan menggunakan
subprocess
modul. Untuk perintah sederhana, ini setara, tetapi menawarkan lebih banyak opsi jika Anda ingin melakukan sesuatu yang rumit.Contoh untuk kasus Anda:
Ini akan berjalan
rm -r some.file
di latar belakang. Perhatikan bahwa memanggil.communicate()
objek yang dikembalikan dariPopen
akan memblokir hingga selesai, jadi jangan lakukan itu jika Anda ingin menjalankannya di latar belakang:Lihat dokumentasi di sini .
Juga, poin klarifikasi: "Latar Belakang" seperti yang Anda gunakan di sini adalah murni konsep shell; secara teknis, yang Anda maksud adalah Anda ingin menelurkan proses tanpa memblokir sementara Anda menunggu untuk menyelesaikannya. Namun, saya telah menggunakan "latar belakang" di sini untuk merujuk pada perilaku seperti latar belakang shell.
sumber
Popen()
untuk menghindari pemblokiran utas utama dan jika Anda memerlukan daemon kemudian lihatpython-daemon
paket untuk memahami bagaimana seharusnya daemon yang didefinisikan dengan baik. Jawaban Anda baik-baik saja jika Anda menghapus semua yang dimulai dengan "Tapi hati-hati" kecuali tautan ke dokumen subproses.Anda mungkin menginginkan jawaban untuk "Cara memanggil perintah eksternal dengan Python" .
Pendekatan paling sederhana adalah dengan menggunakan
os.system
fungsi, misalnya:Pada dasarnya, apa pun yang Anda berikan ke
system
fungsi akan dieksekusi sama seperti jika Anda meneruskannya ke shell dalam sebuah skrip.sumber
Saya menemukan ini di sini :
Di windows (win xp), proses induk tidak akan selesai sampai pekerjaannya
longtask.py
selesai. Ini bukan yang Anda inginkan dalam skrip CGI. Masalahnya tidak spesifik untuk Python, dalam komunitas PHP masalahnya sama.Solusinya adalah dengan melewati
DETACHED_PROCESS
Bendera Proses Pembuatan keCreateProcess
fungsi yang mendasari di win API. Jika Anda menginstal pywin32, Anda dapat mengimpor flag dari modul win32process, jika tidak, Anda harus mendefinisikannya sendiri:sumber
Gunakan
subprocess.Popen()
denganclose_fds=True
parameter, yang akan memungkinkan subproses yang dihasilkan terlepas dari proses Python itu sendiri dan terus berjalan bahkan setelah Python keluar.https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f
sumber
Anda mungkin ingin mulai menyelidiki modul os untuk mencari utas yang berbeda (dengan membuka sesi interaktif dan mengeluarkan bantuan (os)). Fungsi-fungsi yang relevan adalah fork dan fungsi-fungsi eksekutif mana saja. Untuk memberi Anda ide tentang cara memulainya, letakkan sesuatu seperti ini di dalam fungsi yang melakukan fork (fungsi perlu mengambil daftar atau tuple 'args' sebagai argumen yang berisi nama program dan parameternya; Anda mungkin juga ingin untuk mendefinisikan stdin, out, dan err untuk utas baru):
sumber
os.fork()
benar-benar berguna, tetapi memang memiliki kelemahan hanya tersedia di * nix.threading
: stackoverflow.com/a/53751896/895245 Saya pikir itu mungkin bekerja pada Windows.Keduanya menangkap keluaran dan berjalan di latar belakang dengan
threading
Seperti disebutkan pada jawaban ini , jika Anda menangkap output dengan
stdout=
dan kemudian mencobaread()
, maka proses tersebut akan terhambat.Namun, ada kasus di mana Anda membutuhkan ini. Sebagai contoh, saya ingin meluncurkan dua proses yang berbicara melalui port di antara mereka , dan menyimpan stdout mereka ke file log dan stdout.
The
threading
modul memungkinkan kita untuk melakukan itu.Pertama, lihat bagaimana melakukan bagian redirection output saja dalam pertanyaan ini: Python Popen: Menulis ke stdout DAN file log secara bersamaan
Kemudian:
main.py
sleep.py
Setelah berlari:
stdout diperbarui setiap 0,5 detik untuk setiap dua baris mengandung:
dan setiap file log berisi log masing-masing untuk proses yang diberikan.
Terinspirasi oleh: https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Diuji pada Ubuntu 18.04, Python 3.6.7.
sumber