IPC::Open3 and the error filehandle
IPC::Open3 and the error filehandle
am 26.10.2007 15:33:07 von Peter Makholm
I'm trying to use IPC::Open3 but have some problem with the error
filehandle not being used. Try the following script:
#!/usr/bin/perl
use IPC::Open3;
use Data::Dumper;
my ( $in, $out, $err );
open3($in,$out,$err, "/usr/bin/sort");
print Dumper [$in, $out, $err];
__END__
I would expect output like:
$VAR1 = [
\*Symbol::GEN0,
\*Symbol::GEN1,
\*Symbol::GEN2,
];
but I get output like
$VAR1 = [
\*Symbol::GEN0,
\*Symbol::GEN1,
undef
];
Reading the documentation, it clearly states that:
If CHLD_ERR is false, or the same file descriptor as CHLD_OUT, then
STDOUT and STDERR of the child are on the same filehandle. The
CHLD_IN will have autoflush turned on.
and $err is undef, which is clearly false. But what would be the
correct way to call open3?
The following works:
#!/usr/bin/perl
use IPC::Open3;
use Symbol;
use Data::Dumper;
my ( $in, $out, $err );
$err = gensym;
open3($in,$out,$err, "/usr/bin/sort");
print Dumper [$in, $out, $err];
__END__
but calling gensym by hand seems oldschool. But is there a better way?
//Makholm
Re: IPC::Open3 and the error filehandle
am 26.10.2007 21:35:20 von Charles DeRykus
On Oct 26, 6:33 am, Peter Makholm wrote:
> I'm trying to use IPC::Open3 but have some problem with the error
> filehandle not being used. Try the following script:
>
> #!/usr/bin/perl
>
> use IPC::Open3;
> use Data::Dumper;
>
> my ( $in, $out, $err );
> open3($in,$out,$err, "/usr/bin/sort");
>
> print Dumper [$in, $out, $err];
>
> __END__
>
> I would expect output like:
>
> $VAR1 = [
> \*Symbol::GEN0,
> \*Symbol::GEN1,
> \*Symbol::GEN2,
> ];
>
> but I get output like
>
> $VAR1 = [
> \*Symbol::GEN0,
> \*Symbol::GEN1,
> undef
> ];
>
> Reading the documentation, it clearly states that:
>
> If CHLD_ERR is false, or the same file descriptor as CHLD_OUT, then
> STDOUT and STDERR of the child are on the same filehandle. The
> CHLD_IN will have autoflush turned on.
>
> and $err is undef, which is clearly false. But what would be the
> correct way to call open3?
>
> The following works:
>
> #!/usr/bin/perl
>
> use IPC::Open3;
> use Symbol;
> use Data::Dumper;
>
> my ( $in, $out, $err );
> $err = gensym;
> open3($in,$out,$err, "/usr/bin/sort");
>
> print Dumper [$in, $out, $err];
>
> __END__
>
> but calling gensym by hand seems oldschool. But is there a better way?
There was a thread about this not too long ago.
The open3 doc's aren't really informative IMO
since they don't clarify that you usually want to open a stderr
filehandle prior to the open3 call which just dup's to that opened fh.
(unless you pass "" which causes it to use stdout IIRC)
I usually do something like this:
open my $errfh ... or die...
open3( $in, $out, $errfh ) ...
--
Charles DeRykus
Re: IPC::Open3 and the error filehandle
am 26.10.2007 22:22:20 von Ben Morrow
Quoth Peter Makholm :
> I'm trying to use IPC::Open3 but have some problem with the error
> filehandle not being used. Try the following script:
>
> #!/usr/bin/perl
>
> use IPC::Open3;
> use Data::Dumper;
>
> my ( $in, $out, $err );
> open3($in,$out,$err, "/usr/bin/sort");
>
>
> Reading the documentation, it clearly states that:
>
> If CHLD_ERR is false, or the same file descriptor as CHLD_OUT, then
> STDOUT and STDERR of the child are on the same filehandle. The
> CHLD_IN will have autoflush turned on.
>
> and $err is undef, which is clearly false. But what would be the
> correct way to call open3?
>
> The following works:
>
> #!/usr/bin/perl
>
> use IPC::Open3;
> use Symbol;
> use Data::Dumper;
>
> my ( $in, $out, $err );
> $err = gensym;
> open3($in,$out,$err, "/usr/bin/sort");
>
> print Dumper [$in, $out, $err];
>
> __END__
>
> but calling gensym by hand seems oldschool. But is there a better way?
No.
Ben
Re: IPC::Open3 and the error filehandle
am 26.10.2007 22:47:11 von xhoster
Peter Makholm wrote:
>
> but calling gensym by hand seems oldschool. But is there a better way?
There is, but the better way would break backwards compatibility, which is
probably why it hasn't been implemented.
The better way, IMHO, would be to make your own wrapper around open3
that only sends STDERR to STDOUT if ERRFH is false but defined. If ERRFH
is undefined, then it would be converted into a file handle with gensym,
just like the other two are. Maybe this behavior could be put into
IPC::Open3, but only turned on with a import flag. That way backwards
compatibility would be preserved.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
Re: IPC::Open3 and the error filehandle
am 27.10.2007 00:57:20 von Ben Morrow
Quoth xhoster@gmail.com:
> Peter Makholm wrote:
> >
> > but calling gensym by hand seems oldschool. But is there a better way?
>
> There is, but the better way would break backwards compatibility, which is
> probably why it hasn't been implemented.
>
> The better way, IMHO, would be to make your own wrapper around open3
> that only sends STDERR to STDOUT if ERRFH is false but defined. If ERRFH
> is undefined, then it would be converted into a file handle with gensym,
> just like the other two are. Maybe this behavior could be put into
> IPC::Open3, but only turned on with a import flag. That way backwards
> compatibility would be preserved.
Better would be to replace ERRFH iff it is undef-but-an-lvalue.
Something like
sub open3 {
unless (defined $_[2]) {
local $@;
require Symbol;
eval { $_[2] = Symbol::gensym };
}
goto &IPC::Open3::open3;
}
This will keep the behaviour of an explicit
open3 $IN, $OUT, undef, ...;
which is more intuitive than having to use a false-but-defined value,
and matches the behaviour of open.
Ben
Re: IPC::Open3 and the error filehandle
am 29.10.2007 11:48:40 von Peter Makholm
Ben Morrow writes:
> Better would be to replace ERRFH iff it is undef-but-an-lvalue.
> Something like
Thanks to both of you. I'll add something along the lines of this to
our internal code library.
//Makholm