Perl:Windows 上的 exec() 与 Unix
Perl: exec() on Windows vs. Unix
下面的代码在 Unix 上的工作方式与我预期的一样 - system() 调用阻塞,直到子进程完成。
在 Windows 上,虽然它的工作方式有所不同 - system() 仅在子脚本到达 exec() 之前阻塞,然后它立即 returns,并且 exec-ed 子脚本在后台继续到 运行。有没有办法让它像在 Unix 上一样工作?
# main script
my $myCmd = [$^X, 'myScript.pl', 'arg1', 'arg2'];
system($^X, 'runcmd.pl', @$myCmd);
# runcmd.pl
open(STDOUT, '>', 'out.tmp');
open(STDERR, '>', 'err.tmp');
my $exe = shift @ARGV;
unless(exec($exe, @ARGV))
{
close(STDOUT);
close(STDERR);
exit(1);
}
# myScript.pl - any script that runs few seconds and produces some output, e.g:
foreach (1..5)
{
sleep 1;
print "$_\n";
}
不完全是,不。简单的说,exec
改变了当前进程正在执行的程序。 Windows.
不支持此功能
Perl 显然通过在新进程中执行程序并退出现有进程来模仿 exec
。就像在 unix 系统上一样,这会留下一个程序 运行.
通过将 exec
替换为 system
,您可以在 Windows 上获得所需的结果。
或者,完全避免使用第二个程序。 IPC::Run and IPC::Run3 是用于启动其他程序的实体模块。
use IPC::Run qw( run );
run [ $^X, 'myScript.pl', 'arg1', 'arg2' ],
'>', "out.tmp",
'2>', "err.tmp";
即使是低级别但核心 IPC::Open3 也可以在这里工作。
use IPC::Run qw( open3 );
open(local *CHILD_STDOUT, '>', 'out.tmp') or die $!;
open(local *CHILD_STDERR, '>', 'err.tmp') or die $!;
my $pid = open3('<&STDIN', '>&CHILD_STDOUT', '>&CHILD_STDERR',
$^X, 'myScript.pl', 'arg1', 'arg2');
waitpid($pid, 0);
下面的代码在 Unix 上的工作方式与我预期的一样 - system() 调用阻塞,直到子进程完成。 在 Windows 上,虽然它的工作方式有所不同 - system() 仅在子脚本到达 exec() 之前阻塞,然后它立即 returns,并且 exec-ed 子脚本在后台继续到 运行。有没有办法让它像在 Unix 上一样工作?
# main script
my $myCmd = [$^X, 'myScript.pl', 'arg1', 'arg2'];
system($^X, 'runcmd.pl', @$myCmd);
# runcmd.pl
open(STDOUT, '>', 'out.tmp');
open(STDERR, '>', 'err.tmp');
my $exe = shift @ARGV;
unless(exec($exe, @ARGV))
{
close(STDOUT);
close(STDERR);
exit(1);
}
# myScript.pl - any script that runs few seconds and produces some output, e.g:
foreach (1..5)
{
sleep 1;
print "$_\n";
}
不完全是,不。简单的说,exec
改变了当前进程正在执行的程序。 Windows.
Perl 显然通过在新进程中执行程序并退出现有进程来模仿 exec
。就像在 unix 系统上一样,这会留下一个程序 运行.
通过将 exec
替换为 system
,您可以在 Windows 上获得所需的结果。
或者,完全避免使用第二个程序。 IPC::Run and IPC::Run3 是用于启动其他程序的实体模块。
use IPC::Run qw( run );
run [ $^X, 'myScript.pl', 'arg1', 'arg2' ],
'>', "out.tmp",
'2>', "err.tmp";
即使是低级别但核心 IPC::Open3 也可以在这里工作。
use IPC::Run qw( open3 );
open(local *CHILD_STDOUT, '>', 'out.tmp') or die $!;
open(local *CHILD_STDERR, '>', 'err.tmp') or die $!;
my $pid = open3('<&STDIN', '>&CHILD_STDOUT', '>&CHILD_STDERR',
$^X, 'myScript.pl', 'arg1', 'arg2');
waitpid($pid, 0);