【发布时间】:2013-09-26 00:02:02
【问题描述】:
我正在尝试编写一个执行外部程序并停止它的 perl 脚本。
外部程序不会自行停止,因为我应该在它运行的命令 shell 上点击“输入”。
有什么办法可以在 perl 脚本中停止外部程序?
【问题讨论】:
标签: perl
我正在尝试编写一个执行外部程序并停止它的 perl 脚本。
外部程序不会自行停止,因为我应该在它运行的命令 shell 上点击“输入”。
有什么办法可以在 perl 脚本中停止外部程序?
【问题讨论】:
标签: perl
有什么办法可以在 perl 脚本中停止外部程序?
总之,是的。但具体实施取决于您运行应用程序的平台。
在 perl 支持的所有平台上,您都可以使用system() 来调用外部程序。但是您的原始程序将等待外部程序退出,然后什么都不做,因此system() 不适合您的情况。
由于您没有提及您的平台(OS),因此这里应该讨论两个主要平台:
类Unix操作系统:首先你可以fork一个子进程,在子进程中,使用exec调用外部程序。然后在父进程中,你可以等待子进程,当你想停止外部程序时,发送TERM信号(或其他默认终止进程的信号)。
if (($pid = fork) == 0) {
exec("$external_program $arg");
} else {
# do something...
kill "TERM", $pid;
}
Win32 OS:我想提一下,在Win32平台上,子进程forked实际上是一个伪进程,Win32不像Unix那样支持信号方法。您可以按照1 for Win32 中的解决方案,但据我尝试,子进程经常会错过信号,例如,当子进程正在睡眠或等待套接字连接时。 这可能非常不稳定。
相反,Win32::Process 是更好的解决方案。它使用 Win32 API 来创建和操作进程。
use Win32::Process;
use Win32;
Win32::Process::Create($ProcessObj, $external_program, $arg,
0, NORMAL_PRIORITY_CLASS, ".") or die;
# do something ...
$ProcessObj->Kill($exitcode);
基本上就是这样。如果你想要一个跨平台的解决方案,CPAN 上有一个模块Proc::Background,它支持两个平台。
use Proc::Background;
my $proc = Proc::Background->new($command, $arg);
# do something ...
$proc->die;
【讨论】:
我认为您可以在 Perl 中使用 fork 来获取子进程的 pid(进程 ID)。见最后一条评论here。
一旦你有了 pid,你就可以使用你的 Perl 脚本中的 Unix kill (see this site) 命令,使用here 描述的任何方法。
This 问题还表明您可以从您启动的任何程序内部将 pid 写入单独的文件。然后,您可以从调用脚本中读取该文件中的 pid。
【讨论】: