[python] shell = True로 시작된 파이썬 서브 프로세스를 종료하는 방법
다음 명령으로 하위 프로세스를 시작합니다.
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
그러나 내가 사용하여 죽일 때 :
p.terminate()
또는
p.kill()
명령이 백그라운드에서 계속 실행되므로 실제로 프로세스를 종료하는 방법이 궁금합니다.
내가 명령을 실행할 때 다음에 유의하십시오.
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
을 발행하면 성공적으로 종료됩니다 p.terminate()
.
답변
그룹의 모든 프로세스에 신호를 보낼 수 있도록 프로세스 그룹을 사용하십시오 . 이를 위해서는 세션 ID를 첨부해야합니다 생성 된 자식 프로세스의 부모 프로세스에 를 프로세스는 쉘입니다. 이것은 프로세스의 그룹 리더가 될 것입니다. 이제 신호가 프로세스 그룹 리더에게 전송되면이 그룹의 모든 하위 프로세스로 전송됩니다.
코드는 다음과 같습니다.
import os
import signal
import subprocess
# The os.setsid() is passed in the argument preexec_fn so
# it's run after the fork() and before exec() to run the shell.
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
os.killpg(os.getpgid(pro.pid), signal.SIGTERM) # Send the signal to all the process groups
답변
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
p.kill()
p.kill()
쉘 프로세스를 종료하고 cmd
여전히 실행 중입니다.
나는 이것을 통해 편리한 수정을 발견했다.
p = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True)
이로 인해 쉘이 자식 프로세스를 시작하는 대신 cmd가 쉘 프로세스를 상속하게되는데이 프로세스는 종료되지 않습니다. p.pid
그러면 cmd 프로세스의 ID가됩니다.
p.kill()
작동해야합니다.
그래도 이것이 파이프에 어떤 영향을 미칠지 모르겠습니다.
답변
psutil 을 사용할 수 있으면 완벽하게 작동합니다.
import subprocess
import psutil
def kill(proc_pid):
process = psutil.Process(proc_pid)
for proc in process.children(recursive=True):
proc.kill()
process.kill()
proc = subprocess.Popen(["infinite_app", "param"], shell=True)
try:
proc.wait(timeout=3)
except subprocess.TimeoutExpired:
kill(proc.pid)
답변
나는 그것을 사용하여 그것을 할 수있다
from subprocess import Popen
process = Popen(command, shell=True)
Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))
그것은 cmd.exe
내가 명령을 준 프로그램과 프로그램을 죽였습니다 .
(Windows에서)
답변
때 shell=True
쉘이 자식 프로세스이며, 명령은 그 아이입니다. 어떤 그래서 SIGTERM
나 SIGKILL
자식 프로세스 쉘을 죽일 수 있지만, 나는 그것을 할 수있는 좋은 방법을 기억하지 않습니다. 내가 생각할 수있는 가장 좋은 방법은을 사용하는 것입니다 shell=False
. 그렇지 않으면 부모 셸 프로세스를 종료하면 사용되지 않는 셸 프로세스가 남습니다.
답변
이 답변 중 어느 것도 나를 위해 일하지 않았으므로 Im은 작동 한 코드를 남겨 둡니다. 필자의 경우 프로세스를 종료 .kill()
하고 .poll()
리턴 코드를 얻은 후에도 프로세스가 종료되지 않았습니다.
subprocess.Popen
설명서에 따라 :
“… 제대로 작동하는 응용 프로그램을 올바르게 정리하려면 자식 프로세스를 종료하고 통신을 완료해야합니다 …”
proc = subprocess.Popen(...)
try:
outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
내 경우에는 proc.communicate()
전화를 한 후에 실종되었습니다 proc.kill()
. 이것은 프로세스 stdin, stdout …을 정리하고 프로세스를 종료합니다.
답변
Sai가 말했듯이 쉘은 자식이므로 신호가 차단됩니다. 내가 찾은 가장 좋은 방법은 shell = False를 사용하고 shlex를 사용하여 명령 줄을 분할하는 것입니다.
if isinstance(command, unicode):
cmd = command.encode('utf8')
args = shlex.split(cmd)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
그러면 p.kill () 및 p.terminate ()가 예상대로 작동합니다.