1. 前言
你有没有试过Python脚本输出日志的时候,看到日志文件没有及时输出日志。为什么会这样,今天跟大家分享下。
2.实际测试
以下例子是在Python-3.7.4环境下操作,请注意。
例子1:
确保当前环境变量PYTHONUNBUFFERED为空
$ export PYTHONUNBUFFERED=""
新建一个testoutput.py
#!/usr/bin/python# coding=utf-8import syssys.stdout.write("stdout1 ")sys.stderr.write("stderr1 ")sys.stdout.write("stdout2 ")sys.stderr.write("stderr2 ")
执行结果:
$ python3 testoutput.py stderr1 stderr2 stdout1 stdout2
可以看到标准错误stderr是直接输出,无缓冲。
而标准输出stdout意思是行缓冲,而这里没有换行,等到缓存区满了之后,再输出。
例子2:
确保当前环境变量PYTHONUNBUFFERED为空
$ export PYTHONUNBUFFERED=""
新建testoutput2.py
#!/usr/bin/python# coding=utf-8import syssys.stdout.write("stdout1")sys.stderr.write("stderr1")sys.stdout.write("stdout2")sys.stderr.write("stderr2")
执行结果:
$ python3 testoutput2.py stdout1stderr1stdout2stderr2
跟例子2的区别仅仅是多加了个换行"",标准输出stdout就会及时输出。
例子 3:
确保当前环境变量PYTHONUNBUFFERED为空
$ export PYTHONUNBUFFERED=""
新建一个third.py 文件
#!/usr/bin/python# coding=utf-8import subprocessprint('第1行输出')subprocess.run("echo 第2行输出", shell=True, check=True)print('第3行输出')
结果:
$ python3 third.py第1行输出第2行输出第3行输出
而当我们进行重定向的时候会怎样呢?
$ python3 third.py > result.txt-bash-4.1$ cat result.txt 第2行输出第1行输出第3行输出
在这里可以看出print不是及时输出的,如果重定向文件,标准输出stdout和标准错误stderr进行缓存,等缓存区满了以后,再整体输出。
3.怎么及时输出呢?
- 设置环境变量 export PYTHONUNBUFFERED=1,可以加到用户环境变量中去。
- 执行python脚本的时候加上参数-u
4.啥时候需要缓存呢?
主要是为了降低io操作,比如写大文件,就可以进行缓存。
方法如下:
- 设置环境变量为空
export PYTHONUNBUFFERED=
- 执行python脚本的时候不要加上参数-u
5.补充下-u参数说明:
对于3.7以上版本: 标准输出stdout和标准错误stderr全部采用unbuffered(无缓存)。
Changed in version 3.7: The text layer of the stdout and stderr streams now is un
6.结束语
学会了吗?真棒。
喜欢本文的童鞋,可以关注我+收藏。