python sys.stdin.read() 来自 tail -f
python sys.stdin.read() 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
您可以将 sys.stdin
用作迭代器,而不是先尝试从中读取。
def iplookup(srcip):
for ip in srcip:
ip = ip.strip()
try:
print(geolite2.lookup(ip))
except:
pass
iplookup(sys.stdin)
read() 读取直到到达 EOF。
EOF 字符在执行 close() 时添加,或者您可以显式添加它。
您的文件没有任何 EOF。修改您的程序以读取固定大小的块或迭代 leadline()。
您可以使用 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)
从好的方面来说,您的脚本也会自动接受文件名作为参数。
None 的其他答案(甚至 fileinput
)完全解决了缓冲问题,因此不适用于 tail -f
的小输出。
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. To work around this, you will want to use
"sys.stdin.readline()" inside a "while 1:" loop.
换句话说你想要的是:
while True:
line = sys.stdin.readline()
iplookup(line)
为什么 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
您可以将 sys.stdin
用作迭代器,而不是先尝试从中读取。
def iplookup(srcip):
for ip in srcip:
ip = ip.strip()
try:
print(geolite2.lookup(ip))
except:
pass
iplookup(sys.stdin)
read() 读取直到到达 EOF。 EOF 字符在执行 close() 时添加,或者您可以显式添加它。
您的文件没有任何 EOF。修改您的程序以读取固定大小的块或迭代 leadline()。
您可以使用 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)
从好的方面来说,您的脚本也会自动接受文件名作为参数。
None 的其他答案(甚至 fileinput
)完全解决了缓冲问题,因此不适用于 tail -f
的小输出。
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. To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop.
换句话说你想要的是:
while True:
line = sys.stdin.readline()
iplookup(line)