I'm just learning Python but have about 16 years experience with PERL and PHP.
I'm trying to get the output of ngrep and write it to a log file using Python while also tailing the log file. I've seen some examples online but some seem old and outdated and others use shell=True which is discouraged.
In perl I just use something similar to the following
#!/usr/bin/perl
open(NGFH,"ngrep -iW byline $filter");
while ($line = <NGFH>) {
open(LOG,">> /path/to/file.log")
// highlighting, filtering, other sub routine calls
print LOG $line
}
I've gotten tail to work but ngrep doesn't. I'd like to be able to run this infinately and output the stream from ngrep to the log file after filtering. I couldn't get the output from ngrep to show in stdout so that's as far as I've gotten. I was expecting to be able to see the data file tail as the log file was updated and see the output from ngrep. For now i was just using bash to run the following.
echo "." >> /path/to/ngrep.log
Thanks!
Here's what I got so far...
Updated This seems to work now. I wouldn't know how to improve on it though.
import subprocess
import select
import re
log = open('/path/to/ngrep.log','a+',0)
print log.name
n = subprocess.Popen(['ngrep', '-iW', 'byline'],\
stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
p = select.poll()
p.register(n.stdout)
f = subprocess.Popen(['tail','-F','-n','0','/path/to/tailme.log'],\
stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p2 = select.poll()
p2.register(f.stdout)
def srtrepl(match):
if match.group(0) == 'x.x.x.x':
# do something
if match.group(0) == 'x.x.y.y':
# do something else
return '\033[92m'+ match.group(0) + '\033[0m'
while True:
if p.poll(1):
line = n.stdout.readline()
s = re.compile(r'(8.8.(4.4|8.8)|192.168.[0-9]{1,3}.[0-9]{1,3})' )
print s.sub( srtrepl, line )
log.write(n.stdout.readline())
if p2.poll(1):
print f.stdout.readline().rstrip('\n')
To emulate your perl code in Python:
It starts
ngrep
process passingfilter_
variable and appends the output to the log file while allowing you to modify it in Python. See Python: read streaming input from subprocess.communicate() (there could be buffering issues: check whetherngrep
supports--line-buffered
option likegrep
and if you want to tailfile.log
then passbuffering=1
toopen()
, to enable line-buffering (only usable in the text-mode) or calllog_file.flush()
afterlog_file.write(line)
).You could emulate
ngrep
in pure Python too.If you want to read output from several processes concurrently (
ngrep
,tail
in your case) then you need to able to read pipes without blocking e.g., using threads, async.io.