如何在python中生成另一个进程并捕获输出?

如何在python中生成另一个进程并捕获输出?,python,subprocess,tail,ngrep,Python,Subprocess,Tail,Ngrep,我只是在学习Python,但在PERL和PHP方面有大约16年的经验 我试图获取ngrep的输出,并使用Python将其写入日志文件,同时跟踪日志文件。我在网上看到过一些例子,但有些似乎陈旧过时,而另一些则不鼓励使用shell=True 在perl中,我只使用类似于以下内容的内容 #!/usr/bin/perl open(NGFH,"ngrep -iW byline $filter"); while ($line = <NGFH>) { open(LOG,">>

我只是在学习Python,但在PERL和PHP方面有大约16年的经验

我试图获取ngrep的输出,并使用Python将其写入日志文件,同时跟踪日志文件。我在网上看到过一些例子,但有些似乎陈旧过时,而另一些则不鼓励使用shell=True

在perl中,我只使用类似于以下内容的内容

#!/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
}
谢谢

这是我到目前为止得到的

已更新 这似乎现在起作用了。但我不知道如何改进它

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')

要在Python中模拟perl代码,请执行以下操作:

#!/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)
它启动
ngrep
进程传递
filter\uu
变量,并将输出附加到日志文件,同时允许您在Python中修改它。请参阅(可能存在缓冲问题:检查
ngrep
是否支持
--line buffered
选项,如
grep
,如果您想跟踪
文件.log
,则在
日志文件.write(line)
之后调用
日志文件.flush()

您也可以在纯Python中模拟
ngrep



如果您想同时读取多个进程的输出(
ngrep
tail
),那么您需要能够。

为什么需要tail和ngrep?您可以在这里使用“纯”Python代码。@Kay方便,熟悉这些工具,并使用经过良好测试和全面的工具。通常,您会使用(ba/z/c)sh脚本连接这些工具。Perl可以很好地做到这一点,并且提供了在这些工具之间处理数据的更简单方法。Python不适合作为shell脚本。根据您的目标(例如,使用Python作为shell脚本),您可能会发现它很有用,或者。这两个都是外部模块,但易于安装。您想交错日志和grep输出,还是可以先打印一个再打印另一个?@Kay but
ngrep
是一个不同的beast—“ngrep是一个pcap感知工具,允许您指定扩展正则表达式以匹配数据包的数据有效负载”
#!/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)