将输出重定向到文件时的奇怪python行为(使用os.system时)

将输出重定向到文件时的奇怪python行为(使用os.system时),python,redirectstandardoutput,Python,Redirectstandardoutput,我遇到了一个问题,我认为这与重定向输出(操作员)和os.system工作的低水平有关 问题 这是我的密码。我想得到最后两行的文本文件。它工作得很好,但输出的组织方式让我感到困惑 import os # Get list directory within the root directory root_list_dir = [directory for directory in os.listdir(".") if os.path.isdir(directory)] for director

我遇到了一个问题,我认为这与重定向输出(操作员
)和
os.system
工作的低水平有关

问题
这是我的密码。我想得到最后两行的文本文件。它工作得很好,但输出的组织方式让我感到困惑

import os

# Get list directory within the root directory
root_list_dir = [directory for directory in os.listdir(".") if  os.path.isdir(directory)]

for directory in root_list_dir:
    log_path = directory + "/acoustic_model/log/"
    log_list = os.listdir(log_path)

    for i in log_list:
        print("==============================")
        os.system("tail -n 2 " + log_path + "" + i)
当我调用python my_script.py时的标准输出(它按照我的预期工作。由于它是冗余的,所以我切断了大部分输出):

但是,当我将输出重定向到一个文件时(通过调用
python my_script.py>results
),
================
部分总是打印在
结果的末尾:

2018-03-13 14:57:24,852     INFO wav_generation: creating waveform for   31 of   32: TTS8
2018-03-13 14:57:27,999     INFO wav_generation: creating waveform for   32 of   32: TTS9
2018-03-13 15:09:45,300     INFO wav_generation: creating waveform for   31 of   32: TTS8
2018-03-13 15:09:48,499     INFO wav_generation: creating waveform for   32 of   32: TTS9
2018-03-13 14:25:32,699     INFO           main: Develop: DNN -- MCD: 4.875 dB; BAP: 0.183 dB; F0:- RMSE: 26.291 Hz; CORR: 0.792; VUV: 6.487%
2018-03-13 14:25:32,700     INFO           main: Test   : DNN -- MCD: 4.716 dB; BAP: 0.162 dB; F0:- RMSE: 22.129 Hz; CORR: 0.830; VUV: 6.132%
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
谁能给我解释一下这里出了什么问题吗?我很想听到任何信息!
提前感谢

您有两件事要写到stdout,它们都有自己的缓冲区

这是您通常不想使用的众多原因之一

只需使用
flush=True
参数,就可以强制Python在每次输出之后刷新它。或者您甚至可以
打开(sys.stdout.fileno(),'wb',buffering=0)
,然后
将自己的
字节写入其中以禁用缓冲

但这可能是不够的,因为您仍然无法控制操作系统写入的内容。如果您想确保其输出是无缓冲的,或者与Python共享相同的缓冲区,除了使用。正如
os.system
的文档首先说的那样

因此:


为了达到你想要的,这不是完美的,但它可能会起作用。将包含“=============”名称的文件设置为“line.file”。按如下所示更改循环的内部。os.system(“cat line.file”)os.system(“tail-n2”+log_path+“”+i)@ilkyutonylee同样的结果,还是我误解了你的想法?你能进一步解释一下吗?啊,我现在看到你的编辑了,谢谢你的澄清。糟糕的是,我试过了,但结果是一样的。我改变了循环中的第一行和第二行,最后它成功了。我想我明白你的意思了,我将阅读一些关于
子流程的文档。还有一件事让我担心:如果有多个缓冲区,那么输出必须是混合的,对吗?为什么当我把它留给stdout时,它们会像预期的那样好,但是当涉及到文件时,
==
会出现在末尾?这很奇怪me@enamoriaPython中的默认缓冲是在stdout要转到TTY(终端)时逐行执行,而不是(重定向到文件)时逐块执行(通常类似于4K,但这取决于Python版本和平台)。许多其他程序,包括
tail
和shell,也在isatty上有所区别。@enamoria这就是为什么我将代码更改为只将
tail
的所有输出捕获为字符串,然后
print
这样我们就不必担心缓冲区的实际工作方式,因为只有一个缓冲区,Python的。如果您喜欢禁用缓冲或手动刷新,您可以(有时您需要这样做,以提高效率或保持“实时”输出),但更容易出错。
2018-03-13 14:57:24,852     INFO wav_generation: creating waveform for   31 of   32: TTS8
2018-03-13 14:57:27,999     INFO wav_generation: creating waveform for   32 of   32: TTS9
2018-03-13 15:09:45,300     INFO wav_generation: creating waveform for   31 of   32: TTS8
2018-03-13 15:09:48,499     INFO wav_generation: creating waveform for   32 of   32: TTS9
2018-03-13 14:25:32,699     INFO           main: Develop: DNN -- MCD: 4.875 dB; BAP: 0.183 dB; F0:- RMSE: 26.291 Hz; CORR: 0.792; VUV: 6.487%
2018-03-13 14:25:32,700     INFO           main: Test   : DNN -- MCD: 4.716 dB; BAP: 0.162 dB; F0:- RMSE: 22.129 Hz; CORR: 0.830; VUV: 6.132%
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
for i in log_list:
    print("==============================")
    proc = subprocess.run(['tail', '-n', '2', log_path + i], stdout=subprocess.PIPE)
    print(proc.stdout)