【问题标题】:python sys.stdin.read() from tail -fpython sys.stdin.read() from tail -f
【发布时间】:2015-08-03 12:37:53
【问题描述】:

为什么 sys.stdin.read() 不从 tail -f 读取管道输入?

#!/usr/bin/env python
import sys
from geoip import geolite2
def iplookup(srcip):
        for ip in srcip.split("\n"):
                try:
                        print(geolite2.lookup(ip))
                except:
                        pass
source = sys.stdin.read()
iplookup(source)

tail -f /var/log/bleh.log | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])' | python mygeoip.py

【问题讨论】:

  • 1.你确定有输出要读取吗,以及 2.sys.stdin.read() blocks 直到没有更多数据要读取,我怀疑在这种情况下永远不会出现这种情况。

标签: python linux bash stdin geoip


【解决方案1】:

你可以使用fileinput

import sys
from geoip import geolite2
import fileinput

def iplookup(srcip):
        for ip in srcip.split("\n"):
                try:
                        print(geolite2.lookup(ip))
                except:
                        pass

for line in fileinput.input():
    iplookup(line)

从好的方面来说,您的脚本也会自动接受文件名作为参数。

【讨论】:

    【解决方案2】:

    其他答案(甚至fileinput)都没有完全解决缓冲问题,因此不适用于tail -f 的小输出。

    来自the python man page

    请注意,xreadlines()、readlines() 和 文件对象迭代器(“for line in sys.stdin”)不是 受此选项影响。要解决此问题,您将需要使用 在“while 1:”循环中的“sys.stdin.readline()”。

    换句话说,你想要的是:

    while True:
        line = sys.stdin.readline()
        iplookup(line)
    

    【讨论】:

      【解决方案3】:

      您可以使用sys.stdin 作为迭代器,而不是先尝试从中读取。

      def iplookup(srcip):
          for ip in srcip:
              ip = ip.strip()
              try:
                  print(geolite2.lookup(ip))
              except:
                  pass
      
      iplookup(sys.stdin)
      

      【讨论】:

      • 这不适用于此处使用 Python 2.7.12 的 tail -f
      • @cweiske,你能提供一个复制器吗?它当然应该工作——当然不会返回,但目标不是函数返回,而是在内容流入时打印新的查找结果。我想知道是否问题与缓冲有关,这需要更多地了解“此处”和要与之交谈的测试程序(即,向文件中添加了多少项目,以及是否足以超过 LINE_MAX*10 保证的最大缓冲区大小tail 的 POSIX 标准)。
      【解决方案4】:

      read() 读取直到到达 EOF。 执行 close() 时添加 EOF 字符,或者您可以显式添加它。

      您的文件没有任何 EOF。修改您的程序以读取固定大小的块或迭代leadline()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-04
        • 2017-05-10
        • 1970-01-01
        • 2010-11-02
        • 1970-01-01
        • 2023-03-25
        • 2011-02-19
        相关资源
        最近更新 更多