perl - Perl:Windows 与 Unix 上的 exec()
问题描述
下面的代码就像我在 Unix 上所期望的那样工作 - system() 调用块,直到子进程完成。在 Windows 上,虽然它的工作方式不同 - system() 仅在子脚本到达 exec() 之前阻塞,然后它立即返回,并且 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
您可以通过替换为在 Windows 上获得所需的结果system
。
或者,完全避免第二个程序。IPC::Run和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);
推荐阅读
- aem - 组件被删除
- content-management-system - Keystone.js:实现编辑考试和考试问题模型的最佳方式
- docker - 从容器访问本地主机网络而不暴露任何端口?
- javascript - 表单提交时出现额外的查询字符串参数
- grav - Grav CMS 是否有像 Wordpress 这样的媒体库?
- c++ - 在两个 Jenkins 构建中的文件之间运行特定的 diff 命令
- python - 将文本字符串逐行附加到 Python 中的各个行以避免内存错误 - 更快的替代方案?
- pyspark - 使用 spark 替换数组中的现有字段
- winforms - DevExpress Winforms XtraGrid 取消组合列保持原始列顺序
- java - java - 如何在java中具有不同参数的构造函数之间交替?