从文件读取TQDM输出

问题描述

这主要是一个通用的python问题,我在分布式环境中工作,因此我的工作人员将其stdout和stderr写入共享文件系统上的文件中(我无法更改)。我希望启动器脚本读取其中一个文件并实时打印出来,以大致跟踪工作进程,每个进程都使用tqdm输出进度条。我很高兴看到运行tail -f文件可以正确输出进度条,例如这些条在一行上更新,就像在本地运行tqdm时一样。但是,当我尝试使用python将其包装时,请使用以下函数

def follow(job : submitit.Job) -> Iterator[str]:
    with open(job.paths.stdout) as fo:
        with open(job.paths.stderr) as fe:
            while True:
                lo = fo.readline()
                    
                if lo:
                    yield lo         

                le = fe.readline()
                if le:
                    yield le

                if job.state != 'RUNNING' and not (le or lo):
                    break
                else:
                    time.sleep(1)

loglines = follow(job)
for line in loglines:
    print(line,end='',flush=True)

它不执行此操作,例如我得到一个换行符,并且进度条通过打印新行来更新,它似乎无法处理tqdm正在编写的\x1b[A字符。

有没有一种方法可以完全在python中做到这一点?

解决方法

我能够通过以下方式解决此问题:使用读取二进制模式,使用read读取文件的末尾,然后将结果字节解码为ascii,而不是python 3默认的UTF- 8。更新的工作跟踪功能如下:

def follow(job : Job) -> Iterator[str]:
    with open(job.paths.stdout,'rb') as fo:
        with open(job.paths.stderr,'rb') as fe:
            while True:
                lo = fo.read().decode('ascii')
                    
                if lo:
                    yield lo   

                le = fe.read().decode('ascii')
                if le:
                    yield le

                if job.state != 'RUNNING' and not le and not lo:
                    break
                else:
                    time.sleep(0.1)