셸=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)
'Programing' 카테고리의 다른 글
리디렉션 후 손실되는 대응 컨텍스트 (0) | 2022.04.05 |
---|---|
VuetifyJS, 라우터 링크가 커서로 표시되지 않음 (0) | 2022.04.05 |
인쇄 함수 출력(비퍼 파이선 출력)을 플러시하려면 어떻게 해야 하는가? (0) | 2022.04.05 |
Vue 슬롯의 높이 및 너비 계산 (0) | 2022.04.05 |
새로 생성되지 않은 TypeScript 클래스의 생성자 호출 (0) | 2022.04.05 |