简体   繁体   English

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

[英]python sys.stdin.read() from tail -f

How come sys.stdin.read() doesn't read the piped input from tail -f? 为什么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

None of the other answers (even fileinput ) fully addresses the issue of buffering, and so will not work for small outputs of tail -f . 其他答案(甚至fileinput )都没有完全解决缓冲问题,因此不适用于tail -f小输出。

From the python man page : python手册页

Note that there is internal buffering in xreadlines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influenced by this option. 请注意,xreadlines(),readlines()和file-object迭代器(“for sys.stdin中的行”)中存在内部缓冲,不受此选项的影响。 To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop. 要解决此问题,您需要在“while 1:”循环中使用“sys.stdin.readline()”。

In other words what you want is: 换句话说,你想要的是:

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

You can use fileinput : 您可以使用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)

On the plus side, your script automagically accepts filename as parameters as well. 从好的方面来说,您的脚本也会自动接受文件名作为参数。

You can use sys.stdin as an iterator, rather than trying to read from it first. 您可以使用sys.stdin作为迭代器,而不是先尝试从中读取它。

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

iplookup(sys.stdin)

read() reads until EOF is reached. read()读取直到达到EOF。 EOF char is added when close() is performed or you can add it explicitly. 执行close()时添加EOF char,或者可以显式添加。

Your file does not have any EOF. 您的文件没有任何EOF。 Modify your program to read blocks of fixed size or iterate over leadline() instead. 修改程序以读取固定大小的块或替代引线()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM