2017-08-12 119 views
1

我在使用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的解决方案,因为我受限于我有权访问哪些模块。但是,如果真的不能这样做,我会欢迎使用其他模块的示例解决方案。

谢谢。

回答

1

在开始进程时指定DETACHED_PROCESS。这样做的效果是:

DETACHED_PROCESS0x00000008

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

参见Process Creation Flags

原因传递"echo hello from process"作为命令行Win32::Process不起作用是因为echocmd.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 
+0

谢谢您的解决方案。我已经用$ exe = which'gnatmake'来测试它,命令被替换为“gnatmake -v”,并且输出被正确写入output.txt。我也删除了分叉进程,因为我相信这是不必要的。看起来我的真正问题是使用echo命令,因为我仍然无法使用它。但是因为我只是用它来测试,所以我不在乎。 – epsilonjon

+0

我已经测试过这个,它工作完美。感谢您的帮助。 – epsilonjon

相关问题