如何执行外部 Windows 命令并立即返回 Perl?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3928144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I execute an external Windows command and instantly return in Perl?
提问by dferraro
I've tried using system() with fork(), tried exec(), and am still not getting what I need.
我试过将 system() 与 fork() 一起使用,试过 exec(),但仍然没有得到我需要的东西。
I want to write a Perl script which executes, let's say, a different Perl script five times in a row (sending it different parameter values), but I have it run concurrently. I realize I could turn my script into a .pm file and reference it, but I'd prefer to keep the child script independent of the parent...
我想编写一个 Perl 脚本,它可以连续五次执行不同的 Perl 脚本(向它发送不同的参数值),但我让它同时运行。我意识到我可以将我的脚本变成一个 .pm 文件并引用它,但我更愿意让子脚本独立于父脚本......
- system() works, but executes the commands consecutively (makes sense per documentation)
- exec() doesn't work - it only executes the first method (makes sense per doc)
- I added a fork() to the child Perl script and then tried using system()
- this did not work either.
- backtick command ' documents says it works the same as system()...
- system() 工作,但连续执行命令(每个文档都有意义)
- exec() 不起作用 - 它只执行第一个方法(每个文档都有意义)
- 我在子 Perl 脚本中添加了一个 fork(),然后尝试使用 system()
- 这也不起作用。
- 反引号命令'文档说它与 system() 的工作原理相同...
Isn't there a simple way in Perl (I'm using Windows XP) to execute a process, and not care about the return values or anything and just continue on into the next line of the parent script?
在 Perl(我使用的是 Windows XP)中是不是有一种简单的方法来执行一个进程,而不关心返回值或任何东西,而是继续进入父脚本的下一行?
回答by Eric Strom
You can do it like this (fork in the parent, exec in the child):
你可以这样做(在父级中分叉,在子级中执行):
for my $cmd qw(command1 command2 command3) {
exec $cmd unless fork
}
The way that exec $cmd unless fork
works is that fork
will return a true value in the parent (the process id) and will return a false value in the child, thus exec $cmd
only gets run if fork
returns false (aka, in the child).
工作的方式exec $cmd unless fork
是fork
将在父进程中返回一个真值(进程 ID)并在子进程中返回一个假值,因此exec $cmd
只有在fork
返回假(也就是在子进程中)时才会运行。
Or if you want to keep tabs on the process as it runs concurrently:
或者,如果您想在进程并发运行时密切关注它:
my @procs;
for my $cmd qw(cmd1 cmd2 cmd3) {
open my $handle, '-|', $cmd or die $!;
push @procs, $handle;
}
Then you can read from an element of @procs
if you need to.
然后,@procs
如果需要,您可以从 的元素中读取。
Or take a look at one of the many CPAN modules, like Forks::Super
that handle the details of fork management.
或者看看众多 CPAN 模块中的一个,比如Forks::Super
处理分叉管理的细节。
回答by Tanktalus
On Windows, you can give the super-secret 1
flag to the system, IIRC.
在 Windows 上,您可以向1
系统 IIRC提供超级机密标志。
system 1, @cmd;
A Google search for this question on PerlMonks gives: Start an MS window in the background from a Perl script
在 PerlMonks 上对此问题的 Google 搜索给出了:从 Perl 脚本在后台启动 MS 窗口
回答by tster
A very lightweight approach.
一种非常轻量级的方法。
Windows:
视窗:
foreach my $cmd (@cmds)
{
`start $cmd`;
}
Unix:
Unix:
foreach my $cmd (@cmds)
{
`$cmd &`;
}
回答by Matthew Flaschen
You need to fork in the parent, and then exec in the new process. It goes like this, assuming A is the original script, and B is the one you want to do 5 times:
您需要在父进程中 fork,然后在新进程中执行。它是这样的,假设 A 是原始脚本,而 B 是您要执行 5 次的脚本:
A1
fork in A1 -> A1 A2
exec B in A2 -> A1 B2
fork in A1 -> A1 A3 B2
exec B in A3 -> A1 B3 B2
etc.
等等。
回答by socket puppet
A module is overkill for this job. You want to fork
to create a new process and then exec
to run a command in the new process. To run five commands, you need something like:
模块对于这项工作来说太过分了。您想fork
创建一个新进程,然后exec
在新进程中运行命令。要运行五个命令,您需要以下内容:
for (my $i=0; $i<5; $i++) {
if (fork() == 0) {
exec($command[$i]); # Runs command and doesn't return
}
}