2012-10-23 2 views
8

이벤트가 발생했을 때 코드를 실행하기 위해 하이퍼 바이저로로드/언로드되는 일부 스크립트 (현재 회사에서 작업 중)에서 작업하고 있습니다. 실제로 스크립트를 언로드하는 유일한 방법은 Ctrl - 입니다. 나는 프로세스를 자동화하는 파이썬에서 함수를 작성 중이다.리눅스에서 작업하는 동안 파이썬에서 Ctrl-C 키보드 인터럽트를 시뮬레이트합니다.

"done" 문자열을 프로그램의 출력으로 보는 즉시 vprobe을 제거해야한다. 당신이 볼 수 있듯이

lineList = buff.readlines() 
cmd = "vprobe /vprobe/myhello.emt" 
p = subprocess.Popen(args = cmd, shell=True,stdout = buff, universal_newlines = True,preexec_fn=os.setsid) 
while not re.search("done",lineList[-1]): 
     print "waiting" 
os.kill(p.pid,signal.CTRL_C_EVENT) 

, 내가 읽기 + 쓰기 모드로 오픈 buff 파일 기술자에 출력을 쓰고 있어요 : 나는 명령을 실행 subprocess.Popen을 사용하고 . 나는 마지막 줄을 확인한다. 'done'이 있으면 죽일 것입니다. 죄송하지만 CTRL_C_EVENT은 Windows에서만 유효합니다. Linux에서 무엇을 할 수 있습니까?

+3

참고로 예를 들어'상수 문자열로 re.search' 더 나은 '로 표현 될 수없는 lineList에'완료 '상태 [-1] : ...' – nneonneo

+0

그래, 네 말이 맞아. 감사. –

답변

8

당신은 단지 리눅스에 해당하는 signal.SIGINT (인터럽트 신호)을 보낼 수 있다고 생각합니다.

(편집 : 저는 여기에 서브 프로세스를 제어하기 위해이 전략의 사용을 권장하지 않았지만,이 특정한 경우에는 제어 -C가 필요하다고 결정한 것처럼 보입니다. SIGINT가 해줘야합니다.)

+0

안녕하세요, Andrew. 답변 해주셔서 감사합니다. 하지만 실제로, SIGINT는 서브 프로세스 기능 만 죽이고 vprobe는 실행을 계속합니다. 어떻게 그렇게 죽일 지에 대한 아이디어가 있습니까? 감사합니다 –

+1

글쎄, Windows에서 작동하는 경우, 그럼 그 신호가 올바른 장소로 가고 있다는 것을 의미합니다. 그래서, 더 강한 것을 시도하십시오. SIGTERM을 시도해보고, 작동하지 않으면 SIGKLL을 시도하십시오. SIGKILL이 작동하지 않으면 아무 것도하지 않을 것입니다. 하위 프로세스를 다룰 수있는 여러 가지 방법을 살펴 봐야 할 것입니다. –

+0

'Popen ([ 'vprobe', '/vprobe/myhello.emt'], shell = False, ...)'을 시도 했습니까? @Core_Dumped – alk

1

아마도 내가 뭔가를 오해 할 수도 있지만, 원하는대로 결과를 얻는 것은 어렵습니다.

무엇이든간에 먼저 을 쿼리 한 다음 Popen()의 컨텍스트에서 사용하고 maciv lineList이 채워지기를 바랍니다.

은 당신이 아마 원하는 것은 이것은 당신이 라인 방식을 읽고 발견 출력에 따라 적절하게 행동 할 수 vprobe 스크립트에 의해 공급 파이프 끝을 제공

logfile = open("mylogfile", "a") 
p = subprocess.Popen(['vprobe', '/vprobe/myhello.emt'], stdout=subprocess.PIPE, buff, universal_newlines=True, preexec_fn=os.setsid) 
for line in p.stdout: 
    logfile.write(line) 
    if re.search("done", line): 
     break 
    print "waiting" 
os.kill(p.pid, signal.CTRL_C_EVENT) 

같은 것입니다.

+0

이것은 거의 정확하게 수행하고 싶은 것을 제외하고 출력을 일부 파일에서도 인쇄하도록하고 (점검 목적으로 PIPE에 들어가는 것과 함께). 어떻게해야합니까? (나는이 시간에 문법적으로 바란다.) –

+0

그렇게 할 수있는 방법을 제공하여 나의 대답을 편집했다. – glglgl

+0

위의 코드는 훌륭하고 훌륭하게 보입니다. 그러나 stdout을 객체 p의 속성으로 사용하면 파손 된 PIPE 오류가 발생합니다. –

3

Linux에서는 Ctrl-C 키보드 인터럽트를 Popen.send_signal (signal.SIGINT) 기능을 사용하는 프로세스에 프로그래밍 방식으로 보낼 수 있습니다.

import subprocess 
import signal 

.. 
process = subprocess.Popen(..) 
.. 
process.send_signal(signal.SIGINT) 
.. 

차단 명령에 대한 Popen.communicate()를 사용하지 마십시오 ..

관련 문제