2011-02-10 70 views
1

我正在瀏覽大量文件並在其上運行一個命令。我想記錄輸出,如果該命令需要超過5分鐘的文件,我想停止命令並轉到下一個文件。使用python記錄文件和進程超時輸出

我有兩個問題:

  1. 我想要的文件名記錄到輸出文件,也記錄輸出消息。我正在使用Popen來記錄消息並使用communicate,因此它被記錄下來,但是我寫的write()的所有文件名在完成整個任務之前不會被寫入。

  2. 我不知道如何輪詢過程並在5分鐘後退出並轉到下一個文件。

下面簡化代碼:

import os, fnmatch 
import subprocess 
import sys 
f=open('filenames','w') 

'Locate all files matching supplied filename pattern in and below supplied root directory.''' 

def locate(pattern, root=os.curdir):   
    for path, dirs, files in os.walk(os.path.abspath(root)): 
     for filename in fnmatch.filter(files, pattern): 
      yield os.path.join(path, filename) 


for filename in locate("*.dll"): 
    f.write(filename) 
    #cmd defintion is changed for simplicity 
    cmd='cat %s' %filename 
    p=subprocess.Popen(cmd,stdout=f) 
    p.communicate()[0] 
+0

縮進代碼,以便其格式化請:)其斬波換行符等 – loosecannon 2011-02-10 23:30:14

回答

1

下面是我用的,大致爲:

from datetime import datetime 
from time import time 

import subprocess 
import sys 
import threading 
import os 

class Execution(threading.Thread): 
    comm = None 
    proc = None 
    returncode = None 
    stdoutdata = None 
    stderrdate = None 

    def __init__(self, comm): 
    threading.Thread.__init__(self) 
    self.comm = comm 

    def run(self): 
    self.proc = subprocess.Popen(self.comm, bufsize=-1, stdin=None, 
           stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    self.proc.wait() 
    (self.stdoutdata, self.stderrdata) = self.proc.communicate() 
    self.returncode = self.proc.poll() 

for curcommand in somecommandlist: 
    ex = Execution(curcommand) 
    starttime = time() 
    ex.start() 
    ex.join(some_timeout_in_seconds) 

    wastimeout = False 
    if (ex.isAlive()): 
    wastimeout = True 
    print("TIMEOUT OCCURRED @ %s" % (datetime.today(),)) 
    ex.proc.kill() 

    ex.join() 
    endtime = time() 
    duration = endtime - starttime 
    print("DURATION %s" % (duration,)) 

    exitcode = ex.returncode 
    print("EXIT CODE: %s" % (exitcode,)) 
    print somepostprocessing(ex.stdoutdata,ex.stderrdata) 
    sys.stdout.flush() 

基本上是:啓動一個單獨的線程中的過程。這是必要的,因爲threading模塊可讓您等待超時,而subprocess模塊不會。等到超時;檢查線程是否還活着。如果線程是活着的,我們通過終止進程來終止它(在這裏,subprocess給你一個kill()結構,其中threading沒有),並等待線程自行結束。

記住communicate()塊和存儲從孩子的stderr和標準輸出輸出的,所以如果輸出是非常大的,這可能無法正常工作。

+0

謝謝phooji!現在嘗試一下。 – Illusionist 2011-02-10 23:57:58