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

时间:2018-06-19 04:22:40

标签: 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 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时的标准输出(它符合我的期望。我切断了大部分输出,因为它是多余的):

==============================
2018-03-09 00:06:46,594     INFO           main: Develop: DNN -- MCD: 4.891 dB; BAP: 0.185 dB; F0:- RMSE: 26.193 Hz; CORR: 0.794; VUV: 6.372%
2018-03-09 00:06:46,594     INFO           main: Test   : DNN -- MCD: 4.721 dB; BAP: 0.163 dB; F0:- RMSE: 22.119 Hz; CORR: 0.828; VUV: 6.052%
==============================
2018-03-23 17:08:31,564     INFO         labels: loaded /data/thinhnv20/merlin-master/egs/build_your_own_voice/s1/experiments/doanngocle_cutaudio_3k5/test_synthesis/gen-lab/TTS8.lab, 84552 labels
2018-03-23 17:08:32,276     INFO         labels: loaded /data/thinhnv20/merlin-master/egs/build_your_own_voice/s1/experiments/doanngocle_cutaudio_3k5/test_synthesis/gen-lab/TTS7.lab, 82456 labels
==============================
2018-05-18 21:05:26,605     INFO           main: reconstructing waveform(s)
2018-05-18 21:05:26,605     INFO wav_generation: creating waveform for    1 of    1: labspit1
==============================
2018-05-18 21:57:58,600     INFO wav_generation: creating waveform for    1 of    2: labspit1
2018-05-18 21:58:25,779     INFO wav_generation: creating waveform for    2 of    2: labspit2
==============================
2018-05-05 03:06:25,523     INFO           main: Develop: DNN -- MCD: 4.981 dB; BAP: 0.187 dB; F0:- RMSE: 27.926 Hz; CORR: 0.766; VUV: 6.610%
2018-05-05 03:06:25,524     INFO           main: Test   : DNN -- MCD: 4.832 dB; BAP: 0.166 dB; F0:- RMSE: 23.796 Hz; CORR: 0.797; VUV: 6.385%
==============================
2018-05-18 22:04:01,253     INFO wav_generation: creating waveform for    2 of    3: labspit1
2018-05-18 22:04:28,330     INFO wav_generation: creating waveform for    3 of    3: labspit2
==============================
2018-03-10 20:50:44,003     INFO           main: Develop: DNN -- MCD: 4.892 dB; BAP: 0.182 dB; F0:- RMSE: 26.413 Hz; CORR: 0.790; VUV: 6.383%
2018-03-10 20:50:44,003     INFO           main: Test   : DNN -- MCD: 4.717 dB; BAP: 0.161 dB; F0:- RMSE: 21.953 Hz; CORR: 0.832; VUV: 6.134%
==============================
2018-03-13 09:23:05,873     INFO wav_generation: creating waveform for   31 of   32: TTS8
2018-03-13 09:23:08,908     INFO wav_generation: creating waveform for   32 of   32: TTS9

但是当我将输出重定向到文件时(通过调用python my_script.py > results),===============部分始终打印在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%
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================
==============================

有人能解释一下我的错误吗?我很乐意听到任何消息! 提前致谢

1 个答案:

答案 0 :(得分:2)

你有两件事写到stdout,都有自己的缓冲区。

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

只需使用flush=True参数,就可以强制Python在每个print之后刷新输出。或者您甚至可以open(sys.stdout.fileno(), 'wb', buffering=0)然后write使用自己的bytes来禁用缓冲。

但这可能会或可能不够,因为您仍然无法控制os.system写的内容。如果你想确保它的输出是无缓冲的,或者与Python共享相同的缓冲区,除了使用subprocess之外,没有办法解决这个问题。正如os.system的文档首先要说的那样。

所以:

for i in log_list:
    print("==============================")
    proc = subprocess.run(['tail', '-n', '2', log_path + i], stdout=subprocess.PIPE)
    print(proc.stdout)