将 stdout 重定向到文件时使用 GNU 超时

将 stdout 重定向到文件时使用 GNU 超时

假设我有一个可执行文件,我想将 STDOUT 和 STDERR 记录到单独的文件中,如下所示:

python write.py > out 2> err

当我将此命令与 GNU 一起使用时timeout,我的out文件始终为空。为什么会发生这种情况?我该如何解决这个问题?

timeout 5s python write.py > out 2> err

示例 write.py:

#!/bin/bash
import sys, time

i = 0
while True:    
    print i
    print >> sys.stderr, i
    time.sleep(1)
    i += 1

答案1

$ timeout 5s python write.py > out 2> err
$ ls -l out err
-rw-r--r-- 1 yeti yeti 10 Apr  6 08:12 err
-rw-r--r-- 1 yeti yeti  0 Apr  6 08:12 out
$ timeout 5s python -u write.py > out 2> err
$ ls -l out err
-rw-r--r-- 1 yeti yeti 10 Apr  6 08:13 err
-rw-r--r-- 1 yeti yeti 10 Apr  6 08:13 out
$ cmp err out && echo same
same
$ cat out 
0
1
2
3
4

python在 上使用缓冲写入stdout,但不在 上使用stderr。因此,写入的所有内容sys.stderr都会立即写入,但 for 的内容sys.stdout会保留在缓冲区中,直到缓冲区已满,以最大限度地减少写入操作。 5 秒内,缓冲区填充不足,甚至无法写入一次,并timeout终止python解释器。

将选项添加-upython的调用中,写入stdout也将不被缓冲。

您可以通过设置环境变量来强制 Python 程序执行相同的行为PYTHONUNBUFFERED。对于其他程序,您可以使用unbuffer来自预计包或stdbufGNU 核心工具(看关闭管道中的缓冲)。

相关内容