我产生了一些子进程,并希望将输出写入文件和控制台。
我当前的设置采用了我要处理的文件和cmd的字典,然后等待它完成,这很好用,输出被重定向到文件。
listofwork = [
{'cmd':'somecmd1', 'file':'somefilename1.log'},
{'cmd':'somecmd2', 'file':'somefilename2.log'},
{'cmd':'somecmd3', 'file':'somefilename3.log'}
]
logpath = '/logs'
child_processes = []
for work in listofwork:
with io.open(logpath + r'//' + work['file'],mode='wb') as out:
p = subprocess.Popen(work['cmd'], stdout=out, stderr=out)
child_processes.append(p)
for cp in child_processes:
cp.communicate()
基本上我想拥有它并在屏幕上显示输出。我发现了这个问题。
Python Popen: Write to stdout AND log file simultaneously
但我希望保持流分离,以便我可以跟踪当前正在读取的输出并采取相应的行动。
那么如何在不立即合并到stdout的情况下写入日志和屏幕。最方便的是如果它会写入一些我可以手动打印到屏幕的内部数据结构!我需要能够实时打印而不是等待过程结束。(通信),因为这个过程需要几个小时。
我不能使用StringIO,因为它会抛出一个没有属性fileno()
的错误答案 0 :(得分:0)
以下作弊。每个子进程现在执行一些工作(即:在文件中搜索),然后使用tee命令将文件和写入子进程的标准输出。父代码将每个worker标准输出并将其打印到屏幕上。 (如果工作人员没有直接写入屏幕,那就更简单了 - 消息会混杂在一起。)
import multiprocessing, subprocess
listofwork = [
{'cmd':'egrep whiskey recipe.txt', 'log':'booze.log'},
{'cmd':'egrep -v whiskey recipe.txt', 'log':'other.log'},
]
# logpath = '/logs'
def worker(work):
mylog = multiprocessing.get_logger()
logged_cmd = '{cmd} | tee {log}'.format(**work)
mylog.info('cmd: %s', logged_cmd)
res = subprocess.check_output(logged_cmd, shell=True)
mylog.info('res: %s', res)h
return res
pool = multiprocessing.Pool() # one process per CPU
for cmdout in pool.imap_unordered(worker, listofwork):
print 'done:',cmdout
whiskey
bitters
syrup
done: bitters
syrup
done: whiskey