问题描述:使用nohup命令后台执行python,但python中print方法打印结果不能实时输出到nohup后台定向文件,只能在程序结束时一次性输出。典型问题样例:在python中使用了os.system(command)方法,command命令打印的结果可以实时输出至定向文件,而print方法打印结果不能实时输出,问题代码样例如下:
import os
import time
print("###################################")
print("ls start...")
print("###################################")
os.system("ls -l")
print("###################################")
print("ls end!")
print("###################################")
nohup后台执行命令如下:
nohup python nohup_test.py > nohup_test.out 2>&1 &
后台程序执行完成后的nohup_test.out内容如下:
如图所示,nohup_test.out中打印的结果时间顺序不对。
问题原因:python中的print方法在打印时默认是打印到缓冲区,当python程序后台执行时,print方法的打印结果默认会统一打印至缓冲区,直到python程序执行完成后再从缓冲区打印至后台重定向文件,执行python -h可以看到关闭缓冲区的相关帮助,具体如下图所示:
解决方法:常见的解决方法有以下几种:
(1)在后台执行python程序时加上-u参数,关闭打印缓冲区,具体命令如下(推荐,简单便捷,无需更改代码):
nohup python -u nohup_test.py > nohup_test.out 2>&1 &
(2)在代码中引入sys包,在每个print函数之后均加入一行sys.stdout.flush()进行强制刷新标准输出,该方法可以实现在打印缓冲区未满的情况下输出也可以立即发送至终端(不推荐,需要添加代码)。
import sys
print("###################################")
sys.stdout.flush()
print("ls start...")
sys.stdout.flush()
print("###################################")
sys.stdout.flush()
(3)在使用print函数打印时将print函数的flush参数设置为True,该参数默认为False,print函数的定义如下图所示(不推荐,需要添加代码):
print("ls start...", flush=True)
解决后打印结果如下: