如何将Win32 :: Process命令的输出重定向到文本文件?
问题描述:
我在使用Win32 :: Process的Perl脚本中运行一个命令,并且我需要将该命令的输出重定向到一个文本文件。在做了一些研究后,这就是我正在尝试的:如何将Win32 :: Process命令的输出重定向到文本文件?
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
对于控制台程序,新的进程不会继承其父的控制台(默认值)。
原因传递"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命令,因为我仍然无法使用它。但是因为我只是用它来测试,所以我不在乎。 – epsilonjon
我已经测试过这个,它工作完美。感谢您的帮助。 – epsilonjon