Uruchamiam podproces za pomocą następującego polecenia:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
Jednak gdy próbuję zabić za pomocą:
p.terminate()
lub
p.kill()
Polecenie działa w tle, więc zastanawiałem się, jak mogę faktycznie zakończyć proces.
Zauważ, że kiedy uruchamiam polecenie z:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
To kończy się pomyślnie podczas wydawania p.terminate()
.
python
linux
subprocess
kill-process
użytkownik175259
źródło
źródło
cmd
wyglądasz Może zawierać polecenie, które uruchamia kilka procesów do uruchomienia. Nie jest więc jasne, o którym procesie mówisz.shell=True
robi dużej różnicy?Odpowiedzi:
Użyj grupy procesów , aby umożliwić wysyłanie sygnału do całego procesu w grupach. W tym celu powinieneś dołączyć identyfikator sesji do procesu nadrzędnego procesów spawnowanych / potomnych, który w twoim przypadku jest powłoką. Dzięki temu będzie liderem grupy w procesach. Tak więc teraz, gdy sygnał jest wysyłany do lidera grupy procesów, jest on przekazywany do wszystkich procesów potomnych tej grupy.
Oto kod:
źródło
os.setsid
nie jest dostępny w systemie Windows ( docs.python.org/library/os.html#os.setsid ), nie wiem, czy to może pomóc, ale możesz tutaj zajrzeć ( bugs.python.org / issue5115 ), aby uzyskać wgląd w to, jak to zrobić.subprocess.CREATE_NEW_PROCESS_GROUP
do tego?CREATE_NEW_PROCESS_GROUP
może być używany do emulacjistart_new_session=True
w systemie Windowsp.kill()
w końcu zabija proces powłoki icmd
nadal działa.Znalazłem wygodny sposób naprawy:
Spowoduje to, że cmd odziedziczy proces powłoki, zamiast zmuszać powłokę do uruchomienia procesu potomnego, który nie zostanie zabity.
p.pid
będzie wtedy identyfikatorem twojego procesu cmd.p.kill()
powinno działać.Nie wiem jednak, jak to wpłynie na twoją fajkę.
źródło
Jeśli możesz użyć psutil , to działa idealnie:
źródło
AttributeError: 'Process' object has no attribute 'get_children
dlapip install psutil
.Mógłbym to zrobić za pomocą
zabił program
cmd.exe
i program, dla którego wydałem polecenie.(W systemie Windows)
źródło
Popen("TASKKILL /F /IM " + process_name)
jeśli go nie masz, możesz uzyskać go zcommand
parametru.Gdy
shell=True
powłoka jest procesem potomnym, a polecenia są jej potomkami. Więc każdySIGTERM
lubSIGKILL
zabije powłokę, ale nie jego procesów potomnych, a ja nie pamiętam, to dobry sposób, aby to zrobić. Najlepszym sposobem, jaki mogę wymyślić, jest użycieshell=False
, w przeciwnym razie, gdy zabijesz proces powłoki nadrzędnej, pozostawi on niedziałający proces powłoki.źródło
Żadna z tych odpowiedzi nie działała dla mnie, więc zostawiam kod, który działał. W moim przypadku nawet po zabiciu procesu
.kill()
i otrzymaniu.poll()
kodu powrotu proces nie został zakończony.Zgodnie z
subprocess.Popen
dokumentacją :W moim przypadku brakowało połączenia
proc.communicate()
poproc.kill()
. To czyści proces stdin, stdout ... i kończy proces.źródło
Jak powiedział Sai, powłoka jest dzieckiem, więc przechwytuje przez nią sygnały - najlepszym sposobem, jaki znalazłem, jest użycie shell = False i użycie shlex do podzielenia linii poleceń:
Następnie p.kill () i p.terminate () powinny działać zgodnie z oczekiwaniami.
źródło
cwd
argument doPopen
.Czuję, że moglibyśmy użyć:
to nie zabije całego twojego zadania, ale proces z p.pid
źródło
Wiem, że to stare pytanie, ale może pomóc komuś, kto szuka innej metody. Tego używam w systemie Windows do zabijania wywoływanych przeze mnie procesów.
/ IM to nazwa obrazu, możesz także zrobić / PID, jeśli chcesz. / T zabija proces, podobnie jak procesy potomne. Siła / F ją kończy. si, jak już ustawiłem, to sposób, w jaki to robisz bez pokazywania okna CMD. Ten kod jest używany w Pythonie 3.
źródło
Wyślij sygnał do wszystkich procesów w grupie
źródło
Nie widziałem tego tutaj wspomnianego, więc zamieszczam to na wypadek, gdyby ktoś tego potrzebował. Jeśli wszystko, co chcesz zrobić, to upewnić się, że podproces zakończy się powodzeniem, możesz umieścić go w menedżerze kontekstu. Na przykład chciałem, aby moja standardowa drukarka wydrukowała obraz, a użycie menedżera kontekstu zapewniło zakończenie podprocesu.
Uważam, że ta metoda jest również wieloplatformowa.
źródło
shell=True
, zgodnie z pytaniem? Którego nie ma w twoim kodzie.thread.join()
. Mam nadzieję, że to wyjaśni.