2009-10-12 13 views
8

thể trùng lặp:
subprocess with timeoutpython: chạy một quá trình với thời gian chờ và chụp stdout, stderr và trạng thái thoát

là gì cách dễ nhất để làm như sau trong Python:

  • Chạy quy trình bên ngoài
  • Chụp màn hình ở trạng thái chuỗi, stderr và thoát
  • Đặt thời gian chờ.

Tôi muốn một cái gì đó như thế này:

import proc 

try: 
    status, stdout, stderr = proc.run(["ls", "-l"], timeout=10) 
except proc.Timeout: 
    print "failed" 
+2

Để chúng tôi biết nơi bạn đang bắt đầu từ, có bạn xem module 'subprocess'? http://docs.python.org/library/subprocess.html –

+0

không - có vẻ như đó là bước nhảy vọt lớn về phía trước – flybywire

+1

subprocess 'Popen.communicate với thời gian chờ, câu hỏi tương tự: http://stackoverflow.com/questions/1191374/ subprocess-with-timeout – Mark

Trả lời

12

Tôi ghét làm công việc của bản thân mình. Chỉ cần sao chép điều này vào mô-đun proc.py của bạn.

import subprocess 
import time 
import sys 

class Timeout(Exception): 
    pass 

def run(command, timeout=10): 
    proc = subprocess.Popen(command, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    poll_seconds = .250 
    deadline = time.time()+timeout 
    while time.time() < deadline and proc.poll() == None: 
     time.sleep(poll_seconds) 

    if proc.poll() == None: 
     if float(sys.version[:3]) >= 2.6: 
      proc.terminate() 
     raise Timeout() 

    stdout, stderr = proc.communicate() 
    return stdout, stderr, proc.returncode 

if __name__=="__main__": 
    print run(["ls", "-l"]) 
    print run(["find", "/"], timeout=3) #should timeout 
+1

Phiên bản này có thể hết thời gian chờ do tràn bộ đệm ống (khi stdout hoặc stderr ~ 64K). – jfs

+1

Nếu lệnh hết thời gian chờ, bạn sẽ không nhận được bất kỳ đầu ra nào được tạo ra cho đến hết thời gian chờ. –

+0

chạy in (["ping www.redicecn.com"], timeout = 10), tập lệnh đã ném ra ngoại lệ Thời gian chờ, nhưng quá trình ping vẫn đang chạy. – redice

11

Note trên linux với coreutils> = 7.0, bạn có thể thêm vào trước thời gian chờ đến lệnh như:

timeout 1 sleep 1000