【问题标题】:Run perl file from PHP script but not wait for output on Windows Server从 PHP 脚本运行 perl 文件,但不等待 Windows Server 上的输出
【发布时间】:2010-11-26 11:18:30
【问题描述】:

我试图从 php 脚本中执行 perl 脚本。我已经使用各种方法(例如 exec、popen 和 proc_open)进行了这项工作,但我有几个问题需要解决,而老 Google 并没有给我答案。

我需要从 php 文件中运行 .pl 脚本(将一个变量传递给脚本,该脚本是一个数字),但停止 php 脚本等待 .pl 完成(.pl 可能需要 4 -5 小时在服务器上运行)。我不希望 perl 脚本有任何返回输出(perl 脚本将其输出记录到 mysql db)所以我只需要它在服务器上运行并让 php 脚本继续运行。

在运行 apache、php、mysql 的 Windows 机器上运行时,有一些障碍需要克服。

我认为我已经看到了 linux 的解决方案,但它需要保留在 Windows 机器上。

我目前正在尝试使用以下代码的 proc_open 方法(proc_open 行上的 35 是我需要传递给 perl 脚本的测试 ID):

$descriptorspec = array(
0 => array("pipe","r"),
1 => array("pipe","w"),
2 => array("file","./error.log","a")
) ;

proc_close(proc_open('perl perlscript.pl 35', $descriptorspec, $pipes));

$i = 0;
while ($i < 1000) {
   echo ++$i;  
}

现在这段代码确实执行了 perl 脚本,但是我放置在它之后的 while 循环(仅用于测试)永远不会执行(我没有等待 perl 脚本完成以查看它是否执行),因为它必须等待 .请完成。

【问题讨论】:

标签: php perl proc-open


【解决方案1】:

我可以看到 3 个选项:

  • 在您的 perl 脚本中使用 fork 来分叉与分叉后存在的父进程的实际工作。不过,这在 Windows 上可能无法正常运行或根本无法运行,但值得一试。

    请参阅以下“Windows 上的fork”参考:

  • 1234563 http://localhost/...。然后在最坏的情况下通过一些内部 PHP 超时或常规 HTTP 超时来超时 URL 请求。在最坏的情况下,在 Perl 代码中执行相同的技巧,因为 Perl 绝对可以支持通过 LWP 库的 URL 调用以及通过 alarm() 的超时
  • 让调度程序每 X 分钟启动一次您的 Perl 脚本。该脚本应以以下逻辑开头:if (-e $flag_file) { unlink $flag_file; do_long_work() } else { exit 0; } 其中$flag_file 是服务器上的特殊位置(例如C:\temp\myscript_start_perl.txt),do_long_work() 包含需要完成的实际工作。

    然后,当 PHP 脚本需要启动 Perl 脚本时,它会简单地创建一个空标志文件(相同的C:\temp\myscript_start_perl.txt),Perl 脚本会在下次调度程序执行时注意到它。

【讨论】:

  • @Alexandr - 请查看子项目符号中的链接。
【解决方案2】:

有两种可能

  1. 使用“启动”程序。您将无法使用管道,只能使用命令行参数。

  2. 创建一个始终运行的 Perl 程序(在启动时运行或使用 Win32::Daemon)。使用套接字或 http 连接到它。这很容易,因为 CPAN 上有很多现成的服务器

另外,可以从另一个使用 Win32::Job 或 Win32::Process 或其他 CPAN 模块的 Perl 程序执行此操作。

【讨论】:

    【解决方案3】:

    我最近为这样的任务发布了一个模块:Win32::Detached

    将它添加到您的 perl 脚本中,它会自行守护进程,让您的 PHP 脚本继续运行。

    【讨论】:

      【解决方案4】:

      感谢所有回答这个问题的人。经过大量研究并弄乱了不同的解决方案,我终于找到了一些可以满足我们需求的工作。它远非完美,但它有效,所以我不会抱怨太多。

      因为这似乎是其他人想知道的事情,所以我想我分享我的解决方案。

      1. 我从这里下载了一个名为 Hstart (40kb) 的小程序:http://www.ntwind.com/software/utilities/hstart.html

      2. 我将文件解压缩到 c:\windows\system32。

      hstart 程序能够在不打开命令窗口的情况下运行批处理文件。直接调用 .pl 文件是行不通的,所以我必须创建一个 .bat 来调用 .pl,如下所示。

      1. 创建了一个与我的 .pl 文件相同的目录的 .bat 文件,该文件基本上使用本地安装的 perl 并传递一个变量来调用 perl 脚本。如图所示:

        perl script.pl %1

      2. 在我的 PHP 脚本中,我使用以下命令来调用我的 perl 文件。

        $cmd = 'hstart /NOCONSOLE "run.bat '.$id .'" > log.log'; 执行($cmd);

      3. 由于设置了标志,运行 php 文件会导致 hstart 以 noconsole 打开,使用我作为变量传递的 $id 打开 perl 文件,并将隐藏控制台窗口的所有输出发送到指定的 log.log以我的命令。我只能看到 perl.exe 在我的任务管理器中运行。

      正如我所说的远非完美,但它确实有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        • 2018-03-31
        • 2021-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多