如何读取重定向/管道数据?

时间:2015-03-04 04:31:18

标签: python python-2.7

我的日志文件位于:

/mfs/log/scribe/clicklog/*/clicklog_current

我想用Python实时处理,所以我创建了一个transform.py文件:

tail -f /mfs/log/scribe/clicklog/*/clicklog_current | grep 'pattern' | ./transform.py

tranform.py中的

def process_line(line):
    print real_process(line)

问题是:每当process_line有新行时,如何拨打stdin

3 个答案:

答案 0 :(得分:2)

每当重定向或管道发生时,标准输入流将设置为该值。所以你可以直接阅读sys.stdin,就像这样

import sys

for line in sys.stdin:
    process_line(line)

如果缓冲咬你,你可以调整/禁用输入缓冲,如this answer中所述

减少缓冲大小:

import os
import sys

for line in os.fdopen(sys.stdin.fileno(), 'r', 100):
    process_line(line)

现在它最多只缓冲100个字节

禁用缓冲:

引用官方文档,

<强> -u

  

强制stdin,stdout和stderr完全无缓冲。在重要的系统上,还将stdin,stdout和stderr置于二进制模式。

     

请注意,file.readlines()和文件对象(for line in sys.stdin)中存在内部缓冲,不受此选项的影响。要解决此问题,您需要在file.readline()内使用while 1: loop

答案 1 :(得分:1)

fileinput库可能能够满足您的需求。

import fileinput
for line in fileinput.input():
    if line == '': pass
    process_line(line)

答案 2 :(得分:0)

使用tail -f模块使用watchdoggrep可以完全摆脱re部分(尽管在这种情况下,您甚至不需要因为您的搜索条件可以写成简单的成员资格测试。)

这是一个简单的例子(从文档中修改),可以满足您的需求:

import sys
import time
from watchdog.observers import Observer
from watchdog.handlers import FileSystemEventHandler

class WatchFiles(FileSystemEventHandler):

    def process_file(self, event):
        """
        does stuff the file
        """
        with open(event.src_path, 'r') as f:
            for line in f:
                if 'pattern' in line:
                   do_stuff(line)

    def on_modified(self, event):
        self.process_file(event)

    def on_created(self, event):
        self.process_file(event)

if __name__ == "__main__":
    path = sys.argv[1] if len(sys.argv) > 1 else '.'
    observer = Observer()
    observer.schedule(WatchFiles(), path, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

这样,您的应用程序不仅更具可移植性,而且它的所有部分都是自包含的。

相关问题