在 win32 上捕获尚未刷新的命令行输出

发布于 2024-08-20 23:08:15 字数 584 浏览 10 评论 0原文

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

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

我怎样才能捕获这种输出,或者通过仅使用命令行技巧(没有 Perl)将 % 中的每个更改以某种方式附加到日志文件(这样我就可以使用现有的日志文件监视方法),或者使用一些 Perl调用system()后直接捕获它的代码?

(Context: I'm trying to monitor a long-running process from a Perl CGI script. It backs up an MSSQL database and then 7-zips it. So far, the backup part (using WITH STATS=1) outputs to a file, which I can have the browser look at, refreshing every few seconds, and it works.)

I'm trying to use 7zip's command-line utility but capture the progress bar to a file. Unfortunately, unlike SQL backups, where every time another percent is done it outputs another line, 7zip rewinds its output before outputting the new progress data, so that it looks nicer if you're just using it normally on the command-line. The reason this is unfortunate is that normal redirects using >, 1>, and 2> only create a blank file, and no output ever appears in it, except for >, which has no output until the job is done, which isn't very useful for a progress bar.

How can I capture this kind of output, either by having every change in % somehow be appended to a logfile (so I can use my existing method of logfile monitoring) just using command-line trickery (no Perl), or by using some Perl code to capture it directly after calling system()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

客…行舟 2024-08-27 23:08:15

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

$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

If you need to capture the output all at once then this is the code you want:

$var=`echo cmd`;

If you want to read the output line by line then you need this code:

#! 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;
    }
}

Another option is using Windows create process. I know Windows C/C++ create process will allow you to redirect all stdout. Perl has access to this same API call: See Win32::Process.

几度春秋 2024-08-27 23:08:15

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

You can try opening a pipe to read 7zip's output.

呆橘 2024-08-27 23:08:15

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

对于恢复:

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

备份:

  1. 在某处创建一个唯一的目录
  2. fork 7za a -w< /code>
  3. 在目录中找到 .tmp 文件,
  4. 跟踪其大小
  5. .tmp 文件不再存在时,

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

This doesn't answer how to capture output that gets rewound, but it was a useful way of going about it that I ended up using.

For restores:

  1. use 7za l to list the files in the zip file and their sizes
  2. fork 7za e using open my $command
  3. track each file as it comes out with -s $filename and compare to the listing
  4. when all output files are their full size, you're done

For backups:

  1. create a unique dir somewhere
  2. fork 7za a -w
  3. find the .tmp file in the dir
  4. track its size
  5. when the .tmp file no longer exists, you're done

For restores you get enough data to show a percentage done, but for backups you can only show the total file size so far, but you could compare with historical ratios if you're using similar data to get a guestimate. Still, it's more feedback than before (none).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文