【问题标题】:embperl - Using IPC::Open3 to call wkhtmltopdf. STDIN Not workingembperl - 使用 IPC::Open3 调用 wkhtmltopdf.标准输入不工作
【发布时间】:2014-07-13 08:25:21
【问题描述】:

在 embperl 中,我尝试使用 IPC::Open3 模块调用 wkhtmltopdf。

我从 wkhtmltopdf 获得输出(感谢 ikegami),但没有输入到 wkhtmltopdf。

这和这个问题有关:perl / embperl — IPC::Open3

代码如下:

[-
  use warnings;
  use strict;
  use IPC::Open3;
  use POSIX;
  use Symbol;

  my $cmd = '/usr/local/bin/wkhtmltopdf - -';

  my $pdf = '';

  my $string = '<!DOCTYPE html>
  <html>
    <head>
      <title>Hello World</title>
     </head>
     <body>
       Hello World!!!
     </body>
     </html>';

  my $fhOUT = gensym();
  open($fhOUT, '>', '/dev/null') or die $!; 
  dup2(fileno($fhOUT), 1) or die $! if fileno($fhOUT) != 1;
  local *STDOUT;
  open(STDOUT, '>&=', 1) or die $!;

  my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd)  or die "could not run cmd : $cmd : $!\n";

  print HIS_IN $string;
  close(HIS_IN);

  while( <HIS_OUT> ) {
    $pdf .= $_;
  }


  waitpid($pid, 0 ) or die "$!\n";
  my $retval =  $?;
  # print "retval-> $retval<br />\n";

  $http_headers_out{'Content-Type'}         = "application/pdf";
  $http_headers_out{'Content-Disposition'}  = "attachment; filename=pdfTest.pdf";

  $escmode = 0;
-]
[+ $pdf +]

【问题讨论】:

    标签: perl stdin wkhtmltopdf embperl ipcopen3


    【解决方案1】:

    STDIN 的想法相同,但 fd 0 而不是 1。

     open(my $fhIN, '<', '/dev/null') or die $!;
     dup2(fileno($fhIN), 0) or die $! if fileno($fhIN) != 0;
     local *STDIN; open(STDIN, '<&=', 0) or die $!;
    
     open(my $fhOUT, '>', '/dev/null') or die $!;
     dup2(fileno($fhOUT), 1) or die $! if fileno($fhOUT) != 1;
     local *STDOUT; open(STDOUT, '>&=', 1) or die $!;
    
     my $pid = open3(
        local *HIS_IN,
        local *HIS_OUT,
        '>&STDERR',
        $cmd
     );
    
     ...
    

    这假设 fd 0 和 1 是关闭的,就像这里的情况一样。

    【讨论】:

    • 池上你好。感谢您花时间回答。它似乎可以工作,但现在进程列表中出现了一个 defunct processapache 24480 24396 0 14:34 ? 00:00:00 [wkhtmltopdf] &lt;defunct&gt;
    • 一个失效的进程是一个没有被收割的进程(例如使用waitwaitpid)。
    • 我添加了waitpid,当我添加open(my $fhIN, '&lt;', '/dev/null') or die $!; dup2(fileno($fhIN), 0) or die $! if fileno($fhIN) != 0; local *STDIN; open(STDIN, '&lt;&amp;=', 0) or die $!;时它可以工作之后,我无法通过html输出任何内容。它可以很好地写入文件,所以我知道它可以工作,但我无法写入浏览器。
    • 您的系统是文件手和文件描述符严重混乱。看起来我们破坏了您用于输出的文件描述符,因此您需要备份它。
    • 在使用 open3() 部分完成后,如何取消破坏文件描述符/句柄?
    猜你喜欢
    • 2014-07-09
    • 2012-08-17
    • 2012-10-16
    • 2013-12-22
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    相关资源
    最近更新 更多