为什么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
答案 0 :(得分:3)
其他答案(甚至fileinput
)都没有完全解决缓冲问题,因此不适用于tail -f
的小输出。
请注意,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。修改您的程序以读取固定大小的块或替代引线()。