如何将 Win32::Process 命令的输出重定向到文本文件?

How to redirect output of Win32::Process command to text file?

我是 运行 使用 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 文件中,我只得到 "hello from system"。有没有办法使用 Win32::Process 来完成我想要的?

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

我宁愿使用 Win32::Process 的解决方案,因为我只能访问哪些模块。但是,如果确实无法做到这一点,我欢迎使用其他模块的示例解决方案。

谢谢。

您在启动进程时指定了 DETACHED_PROCESS。效果如下:

DETACHED_PROCESS 0x00000008

For console processes, the new process does not inherit its parent's console (the default).

参见 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