2013-12-13 71 views
0

我想在执行Perl-CGI程序中的特定命令期间显示迭代进度栏。我使用CGI::ProgressBar模块来实现这一点。例如,如果我想表明的RKHunter扫描的执行过程中的进度条,这是我写的代码:在执行Perl-CGI命令期间打印进度条

使用CGI ::进度QW /:标准/; $ | = 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的浏览器上显示进度条?

回答

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); 
+0

顺便说一句,使用这种技术,但开放的W /轻微的改变()的参数,你可以排序的观看卷曲命令并创建自己的进度条。我的安装程序有一个GUI,并在后台启动Perl,启动卷曲。你的例程为我解决了令人沮丧的12小时问题! – Volomike