3

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')
11
  • Why would you need tail and ngrep? You could use "pure" Python code in here. Commented Jan 3, 2016 at 1:00
  • @Kay Convenience, familiarity with the tools, and use of well-tested & comprehensive tools. Normally, you'd connect these tools with a (ba/z/c)sh script. Perl can do this very well, and provide easier means of handling data in between those tools. Python is not optimal for acting like a shell script. Commented Jan 3, 2016 at 1:04
  • Depending on your goals (e.g., using Python as a shell script), you might find sh.py useful, or plumbum. Both are externals modules, but easy to install. Commented Jan 3, 2016 at 1:07
  • Do you want to interleave log and grep output or is it okay to print one then the other? Commented Jan 3, 2016 at 1:10
  • 1
    @Kay but ngrep is a different beast - "ngrep is a pcap-aware tool that will allow you to specify extended regular expressions to match against data payloads of packets" Commented Jan 3, 2016 at 1:25

1 Answer 1

1

To emulate your perl code in Python:

#!/usr/bin/env python3
from subprocess import Popen, PIPE

with Popen("ngrep -iW byline".split() + [filter_], stdout=PIPE) as process, \
     open('/path/to/file.log', 'ab') as log_file:
    for line in process.stdout: # read b'\n'-separated lines
        # highlighting, filtering, other function calls
        log_file.write(line)

It starts ngrep process passing filter_ 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 whether ngrep supports --line-buffered option like grep and if you want to tail file.log then pass buffering=1 to open(), to enable line-buffering (only usable in the text-mode) or call log_file.flush() after log_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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.