1

(上下文:我正在尝试从 Perl CGI 脚本监视一个长时间运行的进程。它备份一个 MSSQL 数据库,然后对其进行 7-zip 压缩。到目前为止,备份部分(使用WITH STATS=1)输出到一个文件,我可以让浏览器看一下,每隔几秒刷新一次,它就可以工作了。)

我正在尝试使用 7zip 的命令行实用程序,但将进度条捕获到文件中。不幸的是,与 SQL 备份不同,每次完成另一个百分比时,它都会输出另一行,7zip 在输出新的进度数据之前会回退其输出,因此如果您只是在命令行上正常使用它,它看起来会更好。这是不幸的原因是正常重定向使用>, 1>, 并且2>只创建一个空白文件,并且没有输出出现在其中,除了>,它在工作完成之前没有输出,这对于进度条不是很有用.

我怎样才能捕获这种输出,或者通过使用命令行技巧(没有 Perl)或者通过使用一些 Perl调用后直接捕获的代码system()

4

3 回答 3

1

如果您需要一次捕获所有输出,那么这就是您想要的代码:

$var=`echo cmd`;

如果要逐行读取输出,则需要以下代码:

#! perl -slw
use strict;
use threads qw[ yield async ];
use threads::shared;

my( $cmd, $file ) = @ARGV;
my $done : shared = 0;
my @lines : shared;

async {
    my $pid = open my $CMD, "$cmd |" or die "$cmd : $!";
    open my $fh, '>', $file or die "$file : $!";
    while( <$CMD> ) {
        chomp;
        print $fh $_;         ## output to the file
        push @lines, $_;    ## and push it to a shared array
    }
    $done = 1;
}->detach;

my $n = 0;
while( !$done ) {
    if( @lines ) {            ## lines to be processed
        print pop @lines;   ## process them
    }
    else {
        ## Else nothing to do but wait.
        yield;
    }
}

另一种选择是使用 Windows 创建过程。我知道 Windows C/C++ 创建过程将允许您重定向所有标准输出。Perl 可以访问同样的 API 调用:参见Win32::Process

于 2010-02-05T18:56:46.163 回答
0

这没有回答如何捕获被倒带的输出,但这是我最终使用的一种有用的方法。

对于还原:

  1. 用于7za l列出 zip 文件中的文件及其大小
  2. 7za e使用open my $command
  3. 跟踪每个文件,-s $filename并与列表进行比较
  4. 当所有输出文件都是完整大小时,你就完成了

对于备份:

  1. 在某处创建一个独特的目录
  2. 叉子7za a -w
  3. 在目录中找到.tmp文件
  4. 跟踪它的大小
  5. .tmp文件不再存在时,你就完成了

对于恢复,您可以获得足够的数据来显示完成的百分比,但对于备份,您只能显示到目前为止的总文件大小,但是如果您使用类似的数据来猜测,您可以与历史比率进行比较。尽管如此,它还是比以前更多的反馈(无)。

于 2010-02-10T19:10:26.407 回答
0

您可以尝试打开管道来读取 7zip 的输出。

于 2010-02-05T18:47:34.433 回答