后台运行python程序输出缓冲区问题

本文探讨了后台运行Python程序时遇到的输出缓冲区问题,导致脚本执行完毕后才一次性显示所有输出。通过实验验证,stderr无缓冲,而stdout会被缓冲。解决方案包括使用`-u`参数、调用`sys.stdout.flush()`、脚本开头添加`-u`或设置环境变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

后台运行python程序输出缓冲区问题

问题发现

写脚本给工具使用时,遇到一个问题:用python写的脚本输出的内容没有实时显示在发版工具的输出上,而是等脚本执行完后一次性输出。一开始以为是工具的问题,找了半天也没找到什么问题,最后发现后台运行python程序输出到缓冲区的问题,这里总结一下。

问题描述

为了验证这个问题,写了一个测试脚本,从0到19每秒钟输出一个数字:

vim test.py
#!/usr/local/bin/python
#-*- coding: utf-8 -*-

import sys,time 


for x in xrange(0,20): 
print x 
time.sleep(1)

在命令行下用以下命令直接执行该脚本没有问题:

python test.py

而用以下命令后台执行该脚本时,发现生成了日志文件,但是并没有每秒输出,而是在脚本执行完毕之后一次性输出所有数字:

python test.py > test.log &

从而验证了后台运行python程序输出会先输出到缓冲区,等缓冲区满或者脚本结束后再输出。

网上看到stderr输出是无缓存的,于是再写一个脚本验证该问题:

vim test1.py
#!/usr/local/bin/python
#-*- coding: utf-8 -*-

import sys

sys.stdout.write("stdout1 ")
sys.stderr.write("stderr1 ")
sys.stdout.write("stdout2 ")
sys.stderr.write("stderr2 ")

运行程序后,输出结果如下:

# python test1.py 
stderr1 stderr2 stdout1 stdout2

可以看到stderr的输出都在stdout前面,证明了stderr输出是没有输出到缓冲区的,而stdout有。

通过上面两个实验可得出下面的结论

在linux上后台运行python程序stdout会先输出到缓冲区,等缓冲区满或者脚本结束再输出,而stderr不会先输出到缓冲区。

解决办法

1、运行时加-u参数,如 # python -u test.py

用man查看python的-u参数,说明如下:

Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode. Note that there is internal buffering in xreadlines(), readlines() and file-object iterators (“for line in sys.stdin”) which is not influenced by this option. To work around this, you will want to use “sys.stdin.readline()” inside a “while 1:” loop.

强制stdin,stdout和stderr完全不缓冲。

2、在不要缓冲的每一次print后面添加sys.stdout.flush()函数

3、脚本头部添加-u,如#!/usr/local/bin/python -u,道理同方法1

4、添加环境变量 PYTHONUNBUFFERED=1

参考资料

http://www.jb51.net/article/50508.htm

http://blog.youkuaiyun.com/joeblackzqq/article/details/7220009

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值