为什么egrep的标准输出没有通过管道?

2 投票
1 回答
669 浏览
提问于 2025-04-15 21:22

我遇到了一个关于 egrep 和管道的奇怪问题。

我想过滤一段包含一些以主题名称开头的行的流,比如 "TICK:这是一个滴答消息\n"。

当我尝试用 egrep 来过滤时:
./stream_generator | egrep 'TICK' | ./topic_processor
看起来 topic_processor 根本没有接收到任何消息。

但是,当我使用以下的 Python 脚本时:
./stream_generator | python filter.py --topics TICK | ./topic_processor
一切看起来都正常。

我猜 egrep 也需要一个“刷新”机制,这样说对吗?

这里有没有人能给我一点提示?非常感谢!

import sys
from optparse import OptionParser

if __name__ == '__main__':

    parser = OptionParser()

    parser.add_option("-m", "--topics",
                  action="store", type="string", dest="topics")

    (opts, args) = parser.parse_args()

    topics = opts.topics.split(':')

    while True:
        s = sys.stdin.readline()
        for each in topics:
            if s[0:4] == each:
                sys.stdout.write(s)
                sys.stdout.flush()

1 个回答

3

你有没有让这个命令 ./stream_generator | egrep 'TICK' | ./topic_processor 完全运行完毕?如果这个命令运行完了却没有输出,那就说明问题不在于缓冲,因为当 ./stream_generator 结束时,egrep 会清空它的缓冲区,然后也会结束。

确实,当 egrep 不是直接输出到终端(比如输出到管道或文件)时,它会使用较大的缓冲区,这样可能会让你觉得 egrep 一段时间内没有输出,因为在它的缓冲区里没有足够的数据来触发清空。这种情况在 GNU egrep 中可以通过使用 --line-buffered 选项来改变:

./stream_generator | egrep --line-buffered 'TICK' | ./topic_processor 

撰写回答