Saya meluncurkan subproses dengan perintah berikut:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
Namun, ketika saya mencoba membunuh menggunakan:
p.terminate()
atau
p.kill()
Perintah terus berjalan di latar belakang, jadi saya bertanya-tanya bagaimana saya bisa benar-benar menghentikan proses.
Perhatikan bahwa ketika saya menjalankan perintah dengan:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
Itu berhasil berakhir ketika mengeluarkan p.terminate()
.
python
linux
subprocess
kill-process
pengguna175259
sumber
sumber
cmd
penampilanmu? Ini mungkin berisi perintah yang memicu beberapa proses untuk dimulai. Jadi tidak jelas proses yang Anda bicarakan.shell=True
membuat perbedaan besar?Jawaban:
Gunakan grup proses untuk mengaktifkan pengiriman sinyal ke semua proses dalam grup. Untuk itu, Anda harus melampirkan id sesi ke proses induk dari proses spawned / child, yang merupakan shell dalam kasus Anda. Ini akan menjadikannya pemimpin kelompok dalam proses. Jadi sekarang, ketika sinyal dikirim ke pemimpin grup proses, itu dikirim ke semua proses anak dari grup ini.
Ini kodenya:
sumber
os.setsid
tidak tersedia di windows ( docs.python.org/library/os.html#os.setsid ), saya tidak tahu apakah ini dapat membantu tetapi Anda dapat melihat di sini ( bugs.python.org / issue5115 ) untuk beberapa wawasan tentang bagaimana melakukannya.subprocess.CREATE_NEW_PROCESS_GROUP
hubungannya dengan ini?CREATE_NEW_PROCESS_GROUP
dapat digunakan untuk menirustart_new_session=True
pada Windowsp.kill()
akhirnya membunuh proses shell dancmd
masih berjalan.Saya menemukan perbaikan yang mudah dengan:
Ini akan menyebabkan cmd mewarisi proses shell, alih-alih membuat shell meluncurkan proses anak, yang tidak terbunuh.
p.pid
akan menjadi id dari proses cmd Anda.p.kill()
harus bekerja.Saya tidak tahu apa efek ini pada pipa Anda.
sumber
Jika Anda dapat menggunakan psutil , maka ini berfungsi dengan baik:
sumber
AttributeError: 'Process' object has no attribute 'get_children
untukpip install psutil
.Saya bisa melakukannya dengan menggunakan
itu membunuh
cmd.exe
dan program yang saya berikan perintah untuk.(Di Windows)
sumber
Popen("TASKKILL /F /IM " + process_name)
, jika Anda tidak memilikinya, Anda bisa mendapatkannya daricommand
parameter.Ketika
shell=True
shell adalah proses anak, dan perintahnya adalah anak-anaknya. Jadi, adaSIGTERM
atauSIGKILL
akan membunuh cangkang tetapi tidak proses anaknya, dan saya tidak ingat cara yang baik untuk melakukannya. Cara terbaik yang dapat saya pikirkan adalah menggunakanshell=False
, jika tidak ketika Anda membunuh proses shell induk, itu akan meninggalkan proses shell yang mati.sumber
Tidak satu pun dari jawaban ini bekerja untuk saya sehingga saya meninggalkan kode yang berhasil. Dalam kasus saya bahkan setelah membunuh proses dengan
.kill()
dan mendapatkan.poll()
kode kembali proses tersebut tidak berakhir.Berikut
subprocess.Popen
dokumentasi :Dalam kasus saya, saya kehilangan
proc.communicate()
panggilan setelahproc.kill()
. Ini membersihkan proses stdin, stdout ... dan menghentikan proses.sumber
Seperti yang dikatakan Sai, shell adalah anak, jadi sinyal dicegat olehnya - cara terbaik yang saya temukan adalah menggunakan shell = False dan gunakan shlex untuk membagi baris perintah:
Maka p.kill () dan p.terminate () harus bekerja seperti yang Anda harapkan.
sumber
cwd
argumennyaPopen
.apa yang saya rasa bisa kita gunakan:
ini tidak akan membunuh semua tugas Anda tetapi proses dengan p.pid
sumber
Saya tahu ini adalah pertanyaan lama tetapi ini dapat membantu seseorang mencari metode yang berbeda. Ini yang saya gunakan di windows untuk mematikan proses yang saya panggil.
/ IM adalah nama gambar, Anda juga dapat melakukan / PID jika Anda mau. / T membunuh proses serta proses anak. / F force menghentikannya. si, seperti yang saya atur, adalah bagaimana Anda melakukan ini tanpa menunjukkan jendela CMD. Kode ini digunakan dalam python 3.
sumber
Kirim sinyal ke semua proses dalam grup
sumber
Saya belum melihat ini disebutkan di sini, jadi saya meletakkannya di sana kalau-kalau seseorang membutuhkannya. Jika yang ingin Anda lakukan adalah memastikan bahwa subproses Anda berakhir dengan sukses, Anda bisa memasukkannya ke dalam manajer konteks. Sebagai contoh, saya ingin printer standar saya untuk mencetak gambar dan menggunakan manajer konteks memastikan bahwa subproses dihentikan.
Saya percaya metode ini juga lintas platform.
sumber
shell=True
, sesuai pertanyaan? Yang tidak ada dalam kode Anda.thread.join()
. Semoga ini jelas.