【问题标题】:perl / embperl -- IPC::Open3perl / embperl -- IPC::Open3
【发布时间】:2014-07-09 08:05:32
【问题描述】:

我有一个 perl 和 embperl 两种格式的示例程序

perl 版本作为 CGI 工作,但 embperl 版本不工作。

任何建议或解决方案的指针将不胜感激

操作系统:Linux 版本 2.6.35.6-48.fc14.i686.PAE (...)(gcc 版本 4.5.1 20100924 (Red Hat 4.5.1-4) (GCC))#1 SMP Fri Oct 22 15 :27:53 UTC 2010

注意:我最初将此问题发布到 perlmonks [x] 和 embperl 邮件列表 [x],但没有得到解决方案。

perl 工作脚本

#!/usr/bin/perl
use warnings;
use strict;
use IPC::Open3;

print "Content-type: text/plain\n\n";

my $cmd = 'ls';

my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd);
close(HIS_IN);  # give end of file to kid, or feed him
my @outlines = <HIS_OUT>;              # read till EOF
my @errlines = <HIS_ERR>;              # XXX: block potential if massive
print "STDOUT: ", @outlines, "\n";
print "STDERR: ", @errlines, "\n";

waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;

print "child_exit_status: $child_exit_status\n";

embperl 非工作脚本

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

  my $cmd = 'ls';

  my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd);

  close(HIS_IN);  # give end of file to kid, or feed him

  my @outlines = <HIS_OUT>;              # read till EOF
  my @errlines = <HIS_ERR>;              # XXX: block potential if massive
  print OUT "STDOUT: ", @outlines, "\n";
  print OUT "STDERR: ", @errlines, "\n";

  waitpid( $pid, 0 );
  my $child_exit_status = $? >> 8;

  print OUT "child_exit_status: $child_exit_status\n";
-]

这是我收到的输出

STDERR: ls: write error: Bad file descriptor

child_exit_status: 2

【问题讨论】:

  • fileno(STDOUT) 之前的open3 是什么? IIRC,open3 期望它是 2
  • 请进一步解释您的意思。我的脚本中没有 fileno(STDOUT)。
  • fileno(STDOUT)open3 之前返回什么值?
  • 如果我把 fileno(HIS_OUT) 放在 open3.对于 perl 它不返回任何内容,对于 embperl 则返回 19 或 20。
  • 我要求fileno(STDOUT)。当您使用它时,tied(STDOUT)?1:0 是什么

标签: apache perl mod-perl embperl ipcopen3


【解决方案1】:

open3 重定向与 STDOUT 关联的文件描述符,但它是 fd 1 (您exec 将认为是 STDOUT 的程序)。但它不是1。它甚至没有与之关联的文件描述符!我认为这是open3 中的一个错误。我认为您可以按以下方式解决它:

local *STDOUT;
open(STDOUT, '>&=', 1) or die $!;
...open3...

【讨论】:

  • 我在调用 open3 之前添加了这个并收到以下错误“Perl 代码错误:文件描述符错误”
  • fd 1 已关闭?!?呸!您需要 1)打开任意文件句柄(例如 /dev/null),2)使用 POSIX::dup2 将该描述符复制到描述符 1(如果它还不是 1)。3)然后使用我发布的解决方法。跨度>
  • 这有点超出我的想象...您能否提供或指出 1) 和 2) 的示例。
  • open(my $fh, '&gt;', '/dev/null') or die $!; dup2(fileno($fh), 1) or die $! if fileno($fh) != 1;
  • 这太棒了。可以同样用于 STDIN 吗? open(my $fh, '
【解决方案2】:

非常感谢ikegami!!!!

这是有效的 embperl 代码。附言STDIN 也有类似的问题。我还不知道解决方案,但我认为它是相似的。

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

  $http_headers_out{'Content-Type'} = "text/plain";

  my $cmd = 'ls';

  open(my $fh, '>', '/dev/null') or die $!; 

  dup2(fileno($fh), 1) or die $! if fileno($fh) != 1;

  local *STDOUT;
  open(STDOUT, '>&=', 1) or die $!;

  my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd);

  close(HIS_IN);  # give end of file to kid, or feed him

  my @outlines = <HIS_OUT>;              # read till EOF
  my @errlines = <HIS_ERR>;              # XXX: block potential if massive
  print OUT "STDOUT: ", @outlines, "\n";
  print OUT "STDERR: ", @errlines, "\n";

  waitpid( $pid, 0 );
  my $child_exit_status = $? >> 8;

  print OUT "child_exit_status: $child_exit_status\n";
-]

【讨论】:

    猜你喜欢
    • 2012-08-17
    • 2014-07-13
    • 2013-07-16
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多