解决Shell调用Python时print输出延迟问题:实时获取标准输出流
在Shell脚本中调用Python程序时,常遇到print输出被缓冲导致无法实时获取的问题。本文解析了Python print与sys.stdout.write的关系,通过调用sys.stdout.flush()强制刷新缓冲区,实现了Shell对Python长耗时任务输出流的实时捕获,确保日志追踪的即时性。
本文探讨的应用场景是:通过Shell脚本执行Python文件,并期望通过调用返回值来实时获取Python程序的标准输出流。
原始的Shell脚本实现如下:
cmd='python '$1' '$2' '$3' '$5' '$4 RESULT=eval $cmd echo $RESULT
此前编写的Python程序代码如下:
# coding: utf-8
import time
import json
def execute(_database, _parameter):
print 'sleep start'
sleepTime = 30
print 'sleep ' , sleepTime , 'second.'
time.sleep(sleepTime)
print 'sleep done'
testDic={'doneCode':0,'doneMsg':'Done','logList':'success'}
return json.dumps(testDic, ensure_ascii=False)
if __name__ == "__main__":
p = 'param'
db = 'databsae'
result = execute(db, p)
print result
随后发现的问题在于,Shell脚本无法实时获取Python中的print输出。具体表现为:Shell并非在第一条print语句执行后立即获取内容,而是等待程序运行结束(例如休眠30秒后),一次性获取最后一条print语句的输出。
这种现象导致所有print输出在Shell端表现为一次性获取。对于执行时间较短的Python脚本,这通常没有明显影响;但当Python程序需要长时间运行,且必须通过print输出实时追踪程序进度时,这种延迟会造成较大的困扰。
经过查阅相关资料,可知晓其底层原理:
当我们在Python中调用print输出对象时,实际上执行的是sys.stdout.write(obj+'\n')操作。
print函数将所需内容输出到控制台,并在末尾追加一个换行符。
print语句会调用sys.stdout对象的write方法进行处理。
以下两行代码在功能上是等价的:
sys.stdout.write('hello'+'\n')
print 'hello'
调用sys.stdout.flush()可以强制刷新缓冲区。这意味着,即使系统通常会在缓冲区满或遇到换行符时才写入终端,该调用也会强制将缓冲区内的所有内容立即写入终端。
修改后的Python程序代码如下:
# coding: utf-8
import time
import json
import sys
def execute(_database, _parameter):
print 'time 1:',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
print 'sleep start.'
for i in range(1,10):
print 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:',i
print 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:',i*i
print 'ccccccccccccccccccccccccccccccccccccccccccccccccccccccc:',i+i
sys.stdout.flush()
time.sleep(10)
print 'sleep end '
print 'time 2:',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
testDic={'doneCode':0,'doneMsg':'Done','logList':'success'}
return json.dumps(testDic, ensure_ascii=False)
if __name__ == "__main__":
p = 'param'
db = 'database'
result = execute(db, p)
print result
以上关于实时获取Python print输出流的方法即为完整解决方案,希望能为读者提供参考,并欢迎大家继续支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













