2011-07-03 7 views
1

나는 많은 셸 함수를 호출하는 python 스크립트가 있습니다. 이 스크립트는 터미널에서 대화식으로 실행될 수 있습니다.이 경우 즉시 출력을 표시하거나 crontab에서 호출합니다. 오류 출력을 이메일로 보내고 싶습니다. 하위 프로세스를 사용하여 셸 출력을 리디렉션

나는 쉘 함수를 호출하기위한 도우미 함수를 썼다 :

import subprocess 
import shlex 
import sys 

def shell(cmdline, interactive=True): 
    args = shlex.split(cmdline.encode("ascii")) 
    proc = subprocess.Popen(args, stdout=subprocess.PIPE, 
     stderr=subprocess.PIPE) 
    val = proc.communicate() 
    if interactive is True: 
     if proc.returncode: 
      print "returncode " + str(proc.returncode) 
      print val[1] 
      sys.exit(1) 
     else: 
      print val[0] 
    else: 
     if proc.returncode: 
      print "" 
      # send email with val[0] + val[1] 

if __name__ == "__main__": 
    # example of command that produces non-zero returncode 
    shell("ls -z") 

난 데 문제는 두 가지입니다.

1) 대화식 모드에서 셸 명령이 끝날 때까지 (예 : 몇 분) 완료 될 때까지는 communications() 버퍼 출력 이후 명령이 완전히 완료 될 때까지 아무것도 표시되지 않습니다. 출력을 표시하고 버퍼링을 피할 수있는 방법이 있습니까? 나는 returncode를 검사 할 방법이 필요하다. 그래서 나는 communications()을 사용하고있다.

2) 내가 호출 한 일부 셸 명령은 많은 양의 출력 (예 : 2MB)을 생성 할 수 있습니다. communications()에 대한 documentation은 "데이터 크기가 크거나 무제한 경우이 방법을 사용하지 마십시오."라고 말합니다. 큰 사람이 얼마나 큰지 아는 사람 있습니까?

답변

2

1) 을 사용하는 경우으로 통신하면 하위 프로세스의 출력을 캡처하여 표준 출력으로 보내지 않습니다. 하위 프로세스가 완료 될 때 출력을 보는 유일한 이유는 직접 인쇄하기 때문입니다.

당신이 그것을 실행으로보고를 캡처하거나 모든 것을 포착하고 마지막에만 그것으로 무언가를하지 않는 중 하나를 원하기 때문에, 당신은 표준 출력표준 에러를 떠나하여 대화 형 모드에서 작동하는 방식을 변경할 수 있습니다 ~ 없음. 이렇게하면 하위 프로세스가 프로그램과 동일한 스트림을 사용합니다. 을 기다려야 또한 통화와 통신에 전화를 교체해야합니다 :

if interactive is True: 
    proc = subprocess.Popen(args) 
    proc.wait() 
    if proc.returncode: 
     print "returncode " + str(proc.returncode) 
     sys.exit(1) 
else: 
    proc = subprocess.Popen(args, stdout=subprocess.PIPE, 
     stderr=subprocess.PIPE) 
    val = proc.communicate() 
    if proc.returncode: 
     print "" 
     # send email with val[0] + val[1] 

2) 모두의 많은에 따라 달라집니다, 그래서 너무 큰, "메모리에 저장하기에 너무 큰"입니다 요인. 메모리에 2MB의 데이터를 일시적으로 저장하는 것이 좋을 경우 걱정할 필요가 없습니다.

관련 문제