int*_*tar 26 linux redirection command-line stdout
我有一个 python 程序,它正在慢慢地生成一些输出。
我想在一个文件中捕获它,但我也认为我可以用尾巴观看它。
所以在一个终端中我正在做:
python myprog.py > output.txt
Run Code Online (Sandbox Code Playgroud)
并在另一个终端:
tail -f output.txt
Run Code Online (Sandbox Code Playgroud)
但是在 python 程序运行时,尾巴似乎没有向我显示任何东西。
如果我按 ctrl-c 来杀死 python 脚本,突然尾部output.txt开始填满。但不是在 python 运行时。
我究竟做错了什么?
小智 44
您可能还需要显式刷新缓冲区以使其在生成时通过管道传输。这是因为通常只在管道缓冲区填满(我相信以千字节为单位)以及 stdin 消息结束时才打印输出。这可能是为了节省读/写。您可以在每次打印后执行此操作,或者如果您正在循环,则在循环内的最后一次打印之后执行此操作。
import sys
...
print('Some message')
sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)
小智 34
使用无缓冲标志运行 python:
python -u myprog.py > output.txt
Run Code Online (Sandbox Code Playgroud)
然后将实时打印输出。
n8t*_*8te 19
与其尝试拖尾实时文件,不如使用tee。它被用来做你想做的事情。
来自男士 T 恤:
tee(1) - Linux 手册页
名称 tee - 从标准输入读取并写入标准输出和文件
概要
Run Code Online (Sandbox Code Playgroud)tee [OPTION]... [FILE]...描述
将标准输入复制到每个文件,也复制到标准输出。
Run Code Online (Sandbox Code Playgroud)-a, --append append to the given FILEs, do not overwrite -i, --ignore-interrupts ignore interrupt signals --help display this help and exit --version output version information and exit如果 FILE 是 -,则再次复制到标准输出。
所以在你的情况下,你会运行:
python myprog.py | tee output.txt
Run Code Online (Sandbox Code Playgroud)
编辑:正如其他人所指出的,这个答案将遇到 OP 最初遇到的相同问题,除非sys.stdout.flush()在 Davey 接受的答案中描述的 python 程序中使用。我在发布此答案之前所做的测试并未准确反映 OP 的用例。
tee 仍然可以用作替代方法——尽管不是最佳的——在写入文件的同时显示输出的方法,但戴维的答案显然是正确和最好的答案。
术语:在这种情况下,任何地方都没有管道。(我编辑了问题来解决这个问题)。管道是一种不同类型的文件(内核内部的缓冲区)。
这是重定向到常规文件。
C stdio 和 Python 在连接到 TTY 时默认使 stdout 为行缓冲,否则为全缓冲。行缓冲意味着缓冲区在换行后刷新。全缓冲意味着它只有write()在它已满时才被刷新以对操作系统可见(即通过系统调用)。
您最终会看到输出,一次可能是 4kiB 的块。(我不知道默认缓冲区大小。)这通常更有效,并且意味着对实际磁盘的写入更少。但对于交互式监控来说不是很好,因为输出隐藏在写入过程的内存中,直到它被刷新。
在 Stack Overflow 上,有一个禁用输出缓冲Python 问答,其中列出了许多在 Python 中将无缓冲(或行缓冲?)输出到标准输出的方法。问题本身总结了答案。
选项包括运行python -u(或者我猜放在#!/usr/bin/python -u脚本的顶部),或使用该PYTHONUNBUFFERED程序的环境变量。或者在某些/所有print功能之后显式刷新,就像@Davey 的回答所暗示的那样。
其他一些程序有类似的选项,例如 GNU grep--line-buffered和 GNUsed有-u/ --unbuffered,用于这样的用例,或者例如管道你的 python 程序的输出。例如./slowly-output-stuff | grep --line-buffered 'foo.*bar'。
| 归档时间: |
|
| 查看次数: |
5434 次 |
| 最近记录: |