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

Python 如何读取重定向/管道数据?,python,python-2.7,Python,Python 2.7,我的日志文件位于: /mfs/log/scribe/clicklog/*/clicklog\u current 我想用Python实时处理它,所以我创建了一个transform.py文件: tail-f/mfs/log/scribe/clicklog/*/clicklog|u current|grep'pattern'./transform.py 在tranform.py中: def process_line(line): print real_process(line) 问题是:我如

我的日志文件位于:

/mfs/log/scribe/clicklog/*/clicklog\u current

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

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

tranform.py
中:

def process_line(line):
    print real_process(line)

问题是:我如何调用
process\u line
每次从
stdin
有新行时?

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

import sys

for line in sys.stdin:
    process_line(line)
如果缓冲区咬住了您,您可以调整/禁用输入缓冲,如中所述

减小缓冲区大小:

import os
import sys

for line in os.fdopen(sys.stdin.fileno(), 'r', 100):
    process_line(line)
现在它最多只能缓冲100个字节

禁用缓冲:

import os
import sys

for line in os.fdopen(sys.stdin.fileno(), 'r', 100):
    process_line(line)
引用官方文件

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

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

图书馆也许能满足你的需要

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

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

下面是一个简单的示例(从文档中修改),可以满足您的要求:

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()

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

fileinput在打开输入文件时不会执行阻止操作。在这种情况下,请立即根据我的能力进行更正。您可以使用python等效工具模拟
tail-f
。看看follow.py、cofollow.py和copipe.py,如果我们在python中使用Ctrl-C,我们如何确保编写了部分处理的输出?请参阅.BurhanKhalid,还有更多内容。您希望间歇刷新输出(多久刷新一次?@smci请创建一个新问题,其中包含您的场景的详细信息。这是可行的,但偶尔会得到:
tail:log.txt:file truncated
我认为log.txt文件正在被清除。你有日志旋转或者类似的东西吗?没有,我刚刚创建了
log.txt
,在vim中打开它,运行
tail-f log.txt | python-u transform.py
。然后在
log.txt
中输入行并保存以查看输出。每当保存文件时,vim可能会决定在内部清除该文件。