Tee不显示输出或写入文件

40

我编写了一个Python脚本来监控一些网络资源的状态,可以看作是一个无限的ping程序。它会一直ping同样的3个节点,直到接收到键盘中断。我尝试使用tee将程序的输出重定向到文件,但没有成功:

λ sudo ./pingster.py

15:43:33        node1 SUCESS | node2 SUCESS | node3 SUCESS
15:43:35        node1 SUCESS | node2 SUCESS | node3 SUCESS
15:43:36        node1 SUCESS | node2 SUCESS | node3 SUCESS
15:43:37        node1 SUCESS | node2 SUCESS | node3 SUCESS
15:43:38        node1 SUCESS | node2 SUCESS | node3 SUCESS
^CTraceback (most recent call last):
  File "./pingster.py", line 42, in <module>
    main()
  File "./pingster.py", line 39, in main
    sleep(1)
KeyboardInterrupt

λ sudo ./pingster.py | tee ping.log
# wait a few seconds
^CTraceback (most recent call last):
  File "./pingster.py", line 42, in <module>
    main()
  File "./pingster.py", line 39, in main
    sleep(1)
KeyboardInterrupt

λ file ping.log
ping.log: empty 

我在输出中使用了colorama,我认为这可能是导致问题的原因,但是我在导入colorama之前尝试打印了一些内容,文件仍然为空。我做错了什么呢?
编辑:这是我正在使用的Python文件。
#!/home/nate/py-env/ping/bin/python

from __future__ import print_function
from datetime import datetime
from collections import OrderedDict
from time import sleep

import ping
import colorama


def main():
    d = {
        'node1': '10.0.0.51',
        'node2': '10.0.0.50',
        'node3': '10.0.0.52',
    }
    addresses = OrderedDict(sorted(d.items(), key=lambda t: t[0]))

    colorama.init()
    while True:
        status = []
        time = datetime.now().time().strftime('%H:%M:%S')
        print(time, end='\t')
        for location, ip_address in addresses.items():
            loss, max_time, avg_time = ping.quiet_ping(ip_address, timeout=0.5)
            if loss < 50:
                status.append('{0} SUCESS'.format(location))
            else:
                status.append(
                    '{}{} FAIL{}'.format(
                        colorama.Fore.RED,
                        location,
                        colorama.Fore.RESET,
                    )
                )
        print(' | '.join(status))
        sleep(1)

if __name__ == '__main__':
    main()

Pingster 是如何输出写入的? - Etan Reisner
仅使用Python原生的print函数 - Lily Mara
sudo ./pingster.py | cat 会显示输出吗? - Etan Reisner
不,cat命令也沒有顯示輸出。但是less命令可以使用。 - Lily Mara
2个回答

80

这里有一个更简单的方法来重现你的问题:

$ cat foo.py
from time import sleep
while True: 
  sleep(2)
  print "hello"

$ python foo.py
hello
hello    
(...)

$ python foo.py | tee log
(no output)

这是因为当stdout不是一个终端时,python会缓冲输出。最简单的去除缓冲的方法是使用python -u:
$ python -u foo.py | tee log
hello
hello
(...)

您还可以将Shebang设置为#!/usr/bin/python -u(这无法与env 一起使用)。


9
如果您无法修改python调用,可以将PYTHONUNBUFFERED环境变量设置为非空字符串,这将产生相同的效果。 man python会更详细地描述其行为。 - dimo414

-1
还有另一个原因可以从答案中得出。你正在执行的代码可能位于一个终端复用器(如screen或tmux)中。你的会话是基于伪终端的,所以python缓冲了stdout。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接