perl / embperl -- IPC::Open3



我有一个2种格式的示例程序。embperl

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

如有任何建议或建议,我们将不胜感激

操作系统:Linux version 2.6.35.6-48.fc14.i686。PAE(…)(gcc version 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],但没有得到解决方案。

#!/usr/bin/perl
use warnings;
use strict;
use IPC::Open3;
print "Content-type: text/plainnn";
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_statusn";

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_statusn";
-]

这是我收到的输出

STDERR: ls: write error: Bad file descriptor
child_exit_status: 2

open3重定向与STDOUT相关的文件描述符,除了它是fd 1(您exec的程序将考虑STDOUT)。但它不是1。它甚至没有与之关联的文件描述符!我认为这是open3中的一个bug。我认为你可以这样做:

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

非常感谢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_statusn";
-]

最新更新