我注意到,许多命令行工具,例如wget,将显示进度为一个进程完成时的数字或进度条。虽然问题并不是真正特定于语言的,但在我最常用于命令行工具(C++、Node.js、Haskell)的语言之外,我还没有看到这样做的方法。
下面是一个示例,wget下载文件时终端的单行的三个快照:
除了其他信息外,wget还显示了一个进度条(<=>),它在下载文件时进行了升级。到目前为止下载的数据量(6363,179561,316053)和当前下载速度(10.7KB/s,65.8KB/s,63.0KB/s)更新。这是怎么做的?
理想情况下,请包含上述三种语言中的一种或多种语言的代码示例。
发布于 2015-08-09 03:44:09
只要打印一个CR (没有换行符)就可以覆盖一行。下面是perl中的一个示例程序:
#!/usr/bin/env perl
$| = 1;
for (1..10) {
print "the count is: $_\r";
sleep(1)
}
我还禁用了输出缓冲($| = 1
),以便print命令立即将其输出发送到控制台,而不是缓冲它。
Haskell示例:
import System.IO
import Control.Monad
import Control.Concurrent
main = do
hSetBuffering stdout NoBuffering
forM_ [1..10] $ \i -> do
putStr $ "the count is: " ++ show i ++ "\r"
threadDelay 1000000
发布于 2015-08-09 04:01:36
在GitHub上查看GNU回购-- progress.c
看起来,他们的做法是相同的,即打印一个\r
,然后覆盖。
/* Print the contents of the buffer as a one-line ASCII "image" so
that it can be overwritten next time. */
static void
display_image (char *buf)
{
bool old = log_set_save_context (false);
logputs (LOG_VERBOSE, "\r");
logputs (LOG_VERBOSE, buf);
log_set_save_context (old);
}
发布于 2015-08-09 03:52:04
我只能谈论node.js,但是内置的readline
模块有一些非常基本的内置屏幕处理功能。例如:
var readline = require('readline');
var c = 0;
var intvl = setInterval(function() {
// Clear entirety of current line
readline.clearLine(process.stdout, 0);
readline.cursorTo(process.stdout, 0);
process.stdout.write('Progress: ' + (++c) + '%');
if (c === 100)
clearInterval(intvl);
}, 500);
如果您想变得更时尚,也有第三方模块,例如multimeter
/meterbox
和blessed
/blessed-contrib
。
不过,一般来说,一些程序使用ncurses,而其他程序只是手动输出ANSI转义代码以清除和重新绘制当前行。
https://stackoverflow.com/questions/31900566
复制相似问题