2015-04-23 58 views
0

我有一个测试脚本迭代通过两个字符串数组,我想使用sys.stdout.write为用户提供一个简单的“进度条”。Sys.stdout.write不按预期方式工作

我当前的脚本:

import sys 
from time import sleep 
names = ['Serv1', 'Serv2', 'Serv3', 'Serv4', 'Serv5'] 
states = ['Running', 'Stopped', 'Running', 'Running', 'Stopped'] 
terminated=0 
passed=0 
for i in range (0, len(names)): 
    if 'Running' in states[i]: 
     print " [*] stop if running {0} ".format(str(names[i])) 
     #service_info(action, machine, names[i]) 
     terminated+=1 
    else: 
     print " [!] Passing over {0} ".format(str(names[i])) 
     passed+=1 
    sleep(2) 
    sys.stdout.write(" [ ] {0}/{1} progress left\r".format(i+1, len(names))) 

预期的输出是sys.stdout.write保持更新,而打印报表,通知一些动作的用户。但是当我运行这个时,显示的唯一时间sys.stdout.write在脚本的末尾。例如。

[*] stop if running Serv1 
[!] Passing over Serv2 
[*] stop if running Serv3 
[*] stop if running Serv4 
[!] Passing over Serv5 
[ ] 5/5 progress left 

如何在更新的同时在所有打印照片下方显示进度?

+0

这些都是每行,在默认情况下,你不能回去写上一行。一种方法是清除屏幕并一次又一次地写入所有行或一些窗口API。 http://stackoverflow.com/questions/7122775/python-multiple-line-terminal-update – YOU

+0

我有另一个脚本扫描通过任何主机IP地址的端口,它成功地打印并提供一个进度输出在同一时间。我直接从它复制了一些部分,但在这个例子中似乎不起作用。 –

回答

5

您需要刷新缓冲区;所有输出都被缓冲;保存在内存中,直到收集到一定数量的数据,以提高写入性能。

print声明刷新该缓冲区你,但写stdout直接时候,你需要明确刷新:

sys.stdout.write(" [ ] {0}/{1} progress left\r".format(i+1, len(names))) 
sys.stdout.flush() 

接下来,你在睡觉后写stdout;你接下来要做的就是用下一条print声明替换该行。前睡眠编写短信

for i in range (0, len(names)): 
    if 'Running' in states[i]: 
     print " [*] stop if running {0} ".format(str(names[i])) 
     #service_info(action, machine, names[i]) 
     terminated+=1 
    else: 
     print " [!] Passing over {0} ".format(str(names[i])) 
     passed+=1 
    sys.stdout.write(" [ ] {0}/{1} progress left\r".format(i+1, len(names))) 
    sys.stdout.flush() 
    sleep(2) 
+0

我已经添加了'sys.stdout.flush()',它似乎没有任何区别? –

+0

@LukeWillmer:对,您正在立即打印下一封邮件。移动'sleep()'调用。 –

+0

嗯,似乎我需要'sys.stdout.flush()'以及要移动的睡眠呼叫。谢谢! –