1. 前言
以前写python脚本输出日志的时候,经常看到日志文件没有及时输出日志。这里进行总结一下。
2.例子:
以下例子是在Python-3.7.4环境下操作
例子1:
确保当前环境变量PYTHONUNBUFFERED为空
$ export PYTHONUNBUFFERED=""
新建testoutput.py
#!/usr/bin/python
# coding=utf-8
import sys
sys.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-8
import sys
sys.stdout.write("stdout1\n")
sys.stderr.write("stderr1\n")
sys.stdout.write("stdout2\n")
sys.stderr.write("stderr2\n")
执行结果:
$ python3 testoutput2.py
stdout1
stderr1
stdout2
stderr2
跟例子2的区别仅仅是多加了个换行"\n",标准输出stdout
就会及时输出。
例子 3:
确保当前环境变量PYTHONUNBUFFERED为空
$ export PYTHONUNBUFFERED=""
新建一个first.py 文件
#!/usr/bin/python
# coding=utf-8
import subprocess
print('第1行输出')
subprocess.run("echo 第2行输出", shell=True, check=True)
print('第3行输出')
结果:
$ python3 first.py
第1行输出
第2行输出
第3行输出
而当我们进行重定向的时候会怎样呢?
$ python3 first.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 unbuffered.