我希望在Perl-CGI程序中执行特定命令时显示迭代进度条。我使用CGI::ProgressBar模块来实现这一目标。例如,如果我想在执行RKHunter扫描期间显示进度条,这就是我写的代码:
使用CGI :: ProgressBar qw /:standard /; $ | = 1;
print progress_bar( -from=>1, -to=>100 );
open(my $quik_rk, '-|', 'rkhunter', '--enable', '"known_rkts"') or print "ERROR RUNNING BASIC ROOTKIT CHECK!!";
# print the progress bar while the command executes
while(<$quik_rk>)
{
print update_progress_bar;
#print "<img src=\"ajax-loader.gif\"></img>";
}
close($quik_rk);
这很好用。但是,我在上面的代码之后立即在另一个命令(这个使用Linux Maldet进行扫描)上尝试相同的操作:
open(my $quik_lmd, '-|', 'maldet', '-a', '/home?/?/public_html') or print "ERROR RUNNING BASIC MALWARE CHECK!!";
my $this_ctr = 0;
while(<$quik_lmd>)
{ $this_ctr++;
print update_progress_bar;
}
close($quik_lmd);
进度条不会执行,但te命令本身在后台运行。
我做错了什么? 有没有更好的方法在Perl-CGI中的浏览器上显示进度条?
答案 0 :(得分:1)
我不熟悉RKHunter,但根据你的结果,我的猜测是它为每次运行的测试输出一行文本,而另一个命令没有。
RKHunter输出的每一行文字都会触发<$quik_rk>
的下一次迭代。
第二个命令<$quik_lmd>
,它可能是静默的,因此它永远不会触发循环。命令终止后,在while
。
这里的关键位是“文本行”。 <$filehandle>
运算符每次看到换行符时都会返回一行文本。为了使用这个结构做你想做的事情,你需要强迫第二个命令变得冗长有关它的活动,最重要的是,要用大量的换行符来详细说明。
或者,您可以打开后台流程并使用sleep
来管理您的循环,例如,
use strict;
use POSIX qw(WNOHANG);
my $pid = open(my $quik_rk, '-|', 'sleep', '5'); # replace with your command
do {
print "waiting\n"; # update_progress_bar;
sleep 1; # seconds between update
} while (waitpid($pid, WNOHANG)==0);