如何在 python 中生成另一个进程并捕获输出? [英] How to spawn another process and capture output in 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.
如果您想同时读取多个进程的输出(在您的情况下为ngrep
,tail
),那么您需要能够无阻塞地读取管道,例如,使用线程、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屋!