Python 脚本在终端和重定向到文件之间的输出不同
Python script differs output between terminal and redirection to a file
我正在编写一个包含各种 subprocess.call 的大型 python 脚本来执行系统中可用的命令,但我遇到了一个问题,因为输出会有所不同,无论是打印到终端还是重定向到一个文件。
为了重现问题,这是脚本的一小部分:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import call
print "Hello at first"
call(["rsync", "-aHvz", "root@server1:/tmp/a", '.'])
print "Hello at the end"
从终端 return 以正确的顺序执行它,print + rsync + print:
$ python keepconf.py
Hello at the first
receiving incremental file list
sent 12 bytes received 123 bytes 270.00 bytes/sec
total size is 55858143 speedup is 413764.02
Hello at the end
执行相同的操作,但将输出重定向到文件:
$ python keepconf.py > /tmp/output
$ cat /tmp/output
receiving incremental file list
sent 12 bytes received 123 bytes 270.00 bytes/sec
total size is 55858143 speedup is 413764.02
Hello at the first
Hello at the end
现在的顺序是rsync + print + print。为什么会出现这种行为?
终端(或更准确地说,tty)的输出通常在 Python 中以 行缓冲模式 打开。当您使用管道时,Python 将使用固定大小的不同缓冲区。
这意味着当你用换行符写文本时,缓冲区在打印到终端时会自动刷新,但对于管道它只会在缓冲区已满或强制刷新时刷新(例如当 Python 脚本退出时)。
换句话说,当写入终端时,第一个打印行在 rsync
命令 运行 之前被刷新到终端。重定向到管道时,文本保存在缓冲区中,rsync
命令输出为 运行(刷新时写入管道,最后至少一次,但可能更频繁),之后当 Python 存在时,您向缓冲区写入更多内容,并且该缓冲区被刷新到管道。
您可以手动强制冲洗:
import sys
# ....
print "Hello at first"
sys.stdout.flush()
call(["rsync", "-aHvz", "root@server1:/tmp/a", '.'])
print "Hello at the end"
sys.stdout.flush()
我正在编写一个包含各种 subprocess.call 的大型 python 脚本来执行系统中可用的命令,但我遇到了一个问题,因为输出会有所不同,无论是打印到终端还是重定向到一个文件。
为了重现问题,这是脚本的一小部分:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import call
print "Hello at first"
call(["rsync", "-aHvz", "root@server1:/tmp/a", '.'])
print "Hello at the end"
从终端 return 以正确的顺序执行它,print + rsync + print:
$ python keepconf.py
Hello at the first
receiving incremental file list
sent 12 bytes received 123 bytes 270.00 bytes/sec
total size is 55858143 speedup is 413764.02
Hello at the end
执行相同的操作,但将输出重定向到文件:
$ python keepconf.py > /tmp/output
$ cat /tmp/output
receiving incremental file list
sent 12 bytes received 123 bytes 270.00 bytes/sec
total size is 55858143 speedup is 413764.02
Hello at the first
Hello at the end
现在的顺序是rsync + print + print。为什么会出现这种行为?
终端(或更准确地说,tty)的输出通常在 Python 中以 行缓冲模式 打开。当您使用管道时,Python 将使用固定大小的不同缓冲区。
这意味着当你用换行符写文本时,缓冲区在打印到终端时会自动刷新,但对于管道它只会在缓冲区已满或强制刷新时刷新(例如当 Python 脚本退出时)。
换句话说,当写入终端时,第一个打印行在 rsync
命令 运行 之前被刷新到终端。重定向到管道时,文本保存在缓冲区中,rsync
命令输出为 运行(刷新时写入管道,最后至少一次,但可能更频繁),之后当 Python 存在时,您向缓冲区写入更多内容,并且该缓冲区被刷新到管道。
您可以手动强制冲洗:
import sys
# ....
print "Hello at first"
sys.stdout.flush()
call(["rsync", "-aHvz", "root@server1:/tmp/a", '.'])
print "Hello at the end"
sys.stdout.flush()