实现终端进度条主要是依靠 r
符能将光标移动到行首的能力,下面我们来一步一步的来实现一个终端进度条.
下面的 perl 脚本不出意外会输出 Hello World
#!/usr/bin/perl
use strict;
use warnings;
print "Hello World";
现在用 r
将光标设置到行首
#!/usr/bin/perl
use strict;
use warnings;
print "Hello Worldr";
很多的终端都是带有缓冲,遇到n
才会输出内容,所以这里我们需要强制刷新缓冲区域
#!/usr/bin/perl
use strict;
use warnings;
use IO::Handle;
print "Hello World";
STDOUT->flush();
sleep 1;
print "r";
STDOUT->flush();
sleep 1;
可以看到屏幕输出了 Hello World
,过了一秒钟以后,光标移动到行首了. 下面我们用 #
来充当进度条的内容
#!/usr/bin/perl
use strict;
use warnings;
use IO::Handle;
my $content;
for(my $i = 1; $i < 101; $i++) {
$content = "#" x $i ;
print $content . $i . "%";
STDOUT->flush();
sleep 1;
print "r";
STDOUT->flush();
这样看起来就很像一个真的进度条了,每秒上涨 1%,当然,这里还有一点问题,进度条只能正向上涨,不能下降.还需要简单修改一下,每次需要清理当前行
#!/usr/bin/perl
use strict;
use warnings;
use IO::Handle;
my $max_len = 0;
sub render($) {
if($_[0] > $max_len) {
# 加上后面的两个数字和百分号
$max_len = $_[0] + 3;
}
clean();
my $content = "#" x $_[0];
print $content . $_[0] . "%";
STDOUT->flush();
}
sub clean() {
my $str = sprintf "r%sr", " " x $max_len;
print $str;
STDOUT->flush();
}
while(1) {
my $progress = int(rand(100));
render($progress);
sleep 1;
}
这样执行就非常像一个正确的进度条了