来自tail -f的python sys.stdin.read()

时间:2015-05-21 17:30:46

标签: python linux bash stdin geoip

为什么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

4 个答案:

答案 0 :(得分:3)

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

来自the python man page

  

请注意,xreadlines(),readlines()和中有内部缓冲   文件对象迭代器("用于sys.stdin中的行")不是   受此选项的影响。要解决这个问题,您需要使用   " sys.stdin.readline()"在一个"而1:"循环。

换句话说,你想要的是:

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

答案 1 :(得分:2)

您可以使用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 :(得分:1)

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

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

iplookup(sys.stdin)

答案 3 :(得分:0)

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

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