如何在 python 中生成另一个进程并捕获输出? [英] How to spawn another process and capture output in python?

查看:46
本文介绍了如何在 python 中生成另一个进程并捕获输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm just learning Python but have about 16 years experience with PERL and PHP.

我正在尝试获取 ngrep 的输出并使用 Python 将其写入日志文件,同时还拖尾日志文件.我在网上看过一些例子,但有些看起来陈旧过时,而有些则使用 shell=True,这是不鼓励的.

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.

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

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
}

我已经开始工作了,但 ngrep 没有.我希望能够无限地运行它,并在过滤后将流从 ngrep 输出到日志文件.我无法从 ngrep 获得输出以显示在标准输出中,所以就我所知.我希望能够在日志文件更新时看到数据文件尾部,并看到 ngrep 的输出.现在我只是使用 bash 来运行以下命令.

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

谢谢!

这是我目前得到的...

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

推荐答案

要在 Python 中模拟您的 perl 代码:

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)

它启动 ngrep 进程传递 filter_ 变量并将输出附加到日志文件,同时允许您在 Python 中修改它.请参阅 Python:从 subprocess.communicate() 读取流输入(可能存在缓冲问题:检查 ngrep 支持 --line-buffered 选项,如 grep,如果你想拖尾 file.log 然后 buffering=1 传递给open(),以启用行缓冲(仅在文本模式下可用) 或在 log_file.write(line) 之后调用 log_file.flush().

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

您也可以在纯 Python 中模拟 ngrep.

You could emulate ngrep in pure Python too.

如果您想同时读取多个进程的输出(在您的情况下为ngreptail),那么您需要能够无阻塞地读取管道,例如,使用线程、async.io.

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.

这篇关于如何在 python 中生成另一个进程并捕获输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆