Programing

셸=True로 시작된 python 하위 프로세스를 종료하는 방법

c10106 2022. 4. 5. 22:01
반응형

셸=True로 시작된 python 하위 프로세스를 종료하는 방법

다음 명령으로 하위 프로세스를 시작할 겁니다.

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)

I can do it with use

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그렇지 않으면 부모 껍질 과정을 죽일 때, 그것은 사라진 껍질 과정을 남길 것이다.

나는 이 대답들 중 하나도 듣지 못했기 때문에 나는 그 코드를 남겨두었다.내 경우는 공정을 죽이고도.kill()그리고 a를 받는 것.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... 그리고 프로세스가 종료된다.

사이이가 말한 대로 껍데기가 어린 아이라 신호가 거기에 의해 가로채진다. 내가 발견한 최선의 방법은 셸=거짓말을 사용하고 셸렉스를 사용하여 명령줄을 나누는 것이다.

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.termate()는 어떻게 당신이 기대하는 대로 작용해야 한다.

그룹의 모든 프로세스에 신호 보내기

    self.proc = Popen(commands, 
            stdout=PIPE, 
            stderr=STDOUT, 
            universal_newlines=True, 
            preexec_fn=os.setsid)

    os.killpg(os.getpgid(self.proc.pid), signal.SIGHUP)
    os.killpg(os.getpgid(self.proc.pid), signal.SIGTERM)

을 위한 아주 간단한 방법이 있다.Python 3.5또는 +(실제 테스트 대상:Python 3.8)

import subprocess, signal, time
p = subprocess.Popen(['cmd'], shell=True)
time.sleep(5) #Wait 5 secs before killing
p.send_signal(signal.CTRL_C_EVENT)

그러면, 키보드 입력 탐지가 있거나 이런 것이 있을 때 어느 시점에 코드가 충돌할 수 있다.이 경우 오류가 발생한 코드/기능 라인에서 다음을 사용하십시오.

try:
    FailingCode #here goes the code which is raising KeyboardInterrupt
except KeyboardInterrupt:
    pass

이 코드가 하는 일은 단지 실행 중인 프로세스에 CTRLC"+" 신호를 보내는 것 뿐인데, 이 과정이 죽게 만드는 것은 무엇인가.

내게 효과가 있었던 해결책

if os.name == 'nt':  # windows
    subprocess.Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))
else:
    os.kill(process.pid, signal.SIGTERM)

참조URL: https://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true

반응형