【问题标题】:How to redirect output of Win32::Process command to text file?如何将 Win32::Process 命令的输出重定向到文本文件?
【发布时间】:2017-08-13 08:08:38
【问题描述】:

我正在使用 Win32::Process 在 Perl 脚本中运行命令,我需要将该命令的输出重定向到文本文件。在做了一些研究之后,这就是我正在尝试的:

use Win32::Process;

open (OLDOUT, ">&STDOUT");
open (OLDERR, ">&STDERR");
my $file = "output.txt";
open (STDOUT, ">$file");
open (STDERR, ">&STDOUT");

my $timeout = 1000 * 60; # 60 second timeout
my $proc;
my $exit;
my $exe = "C:/Windows/System32/cmd.exe";
Win32::Process::Create($proc, $exe, "echo hello from process", 1, DETACHED_PROCESS, ".");
$proc->Wait($timeout);
$proc->GetExitCode($exit);

system("echo hello from system"); # To verify that the redirect is working

close (STDOUT);
close (STDERR);
open (STDOUT, ">&OLDOUT");
open (STDERR, ">&OLDERR");
close (OLDOUT);
close (OLDERR);

不幸的是,这不起作用。在 output.txt 文件中,我只得到“来自系统的你好”。有没有办法使用 Win32::Process 完成我想要的?

我使用 Win32::Process 而不是反引号的原因是因为我的命令有时会崩溃,并且我需要提供超时以便在必要时终止它。 Win32::Process 的 ->Wait() 函数允许我这样做。

我宁愿有一个使用 Win32::Process 的解决方案,因为我受限于我可以访问的模块。但是,如果这真的做不到,我会欢迎使用其他模块的示例解决方案。

谢谢。

【问题讨论】:

    标签: perl winapi win32-process


    【解决方案1】:

    您在启动进程时指定DETACHED_PROCESS。这样做的效果如下:

    DETACHED_PROCESS0x00000008

    对于控制台进程,新进程不会继承其父控制台(默认)。

    Process Creation Flags

    "echo hello from process" 作为命令行传递给Win32::Process 不起作用的原因是echo 是一个cmd.exe 内置函数。您需要改为使用命令行'cmd /c "echo hello from process"',如下所示:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use File::Which qw(which);
    use Win32;
    use Win32::Process;
    
    open OLDOUT, ">&STDOUT";
    open OLDERR, ">&STDERR";
    
    my $file = 'output.txt';
    
    open STDOUT, ">$file";
    open STDERR, ">&STDOUT";
    
    my $timeout = 15 * 1_000;
    my ($proc, $exit);
    my $exe = which 'cmd.exe';
    Win32::Process::Create($proc, $exe, 'cmd /c "echo hello from spawned process"', 1, 0, '.');
    $proc->Wait($timeout);
    $proc->GetExitCode($exit);
    
    print "Doing work ...\n"; sleep 3;
    
    print "Spawned process exited with $exit\n";
    
    close STDERR;
    close STDOUT;
    open STDERR, ">&OLDERR";
    open STDOUT, ">&OLDOUT";
    close OLDERR;
    close OLDOUT;
    

    output.txt的内容:

    $ perl main.pl
    
    $ type output.txt
    hello from spawned process
    Doing work ...
    Spawned process exited with 0
    

    【讨论】:

    • 感谢您的解决方案。我已经用 $exe = which 'gnatmake' 对其进行了测试,并将命令替换为“gnatmake -v”,并且输出正确写入了 output.txt。我还删除了分叉进程,因为我认为这是不必要的。看来我真正的问题是 echo 命令,因为我仍然无法让它与它一起工作。但由于我只是用它来测试,我不在乎。
    • 我已经对此进行了测试,它运行良好。感谢您的帮助。
    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 2013-11-15
    相关资源
    最近更新 更多