can't get STDERR using open3...

R

r.u

Hi folks,
I'm flummuxed. I just can't get the function below to capture
the output from STDERR of a program (ploticus in case, but
anything that writes to STDERR will do) in $err. It always
arrives in $out. Any ideas???

-RU

--snip--
sub run_ploticus
{
my $param_ref = shift;

my $debug = 0;

my ($read_fh, $write_fh, $err_fh);

$debug && print "run_ploticus()\n";

my @cmd = ($PLOTICUS_CMD, @{ $param_ref });
$debug && print "CMD: [", join(' ', @cmd), "]\n";

my $pid = open3($write_fh, $read_fh, $err_fh, @cmd);

close($write_fh);

# read output until EOF
my ($rout, $rin, $eout, $ein);
$rin = $ein = '';
my $nclosed = 0;
my ($buf, $ret, $out, $err);
my ($out_open, $err_open) = (1, 1);

my $want_closed = 0;
if (defined($read_fh)) {
vec($rin, fileno($read_fh), 1) = 1;
$want_closed++;
}

if (defined($err_fh)) {
vec($ein, fileno($err_fh), 1) = 1;
$want_closed++;
}

$debug && print " going into read loop...\n";
while ($nclosed < $want_closed) {
$debug && print "top of while, nclosed=[$nclosed]\n";
my $nfound = select($rout=$rin, undef, $eout=$ein, undef);
$debug && print "after select, nfound=[$nfound]\n";
if ($nfound) {
if ($eout) {
$debug && print "stderr has something...\n";
$ret = sysread($err_fh, $buf, 512);
$debug && print "read [$ret] bytes\n";
if ($ret == 0) {
$nclosed++;
$debug && print "incrementing nclosed\n";
$err_open = 0;
next;
}
$debug && print " STDERR: [$buf]\n";
$err .= $buf;
}
if ($rout)
{
$debug && print "stdout has something...\n";
$ret = sysread($read_fh, $buf, 512);
$debug && print "read [$ret] bytes\n";
if ($ret == 0) {
$nclosed++;
$debug && print "incrementing nclosed\n";
$out_open = 0;
next;
}
$debug && print " STDOUT: [$buf]\n";
$out .= $buf;
}
}
}

defined($read_fh) && close($read_fh);
defined($err_fh) && close($err_fh);

waitpid($pid, 0);
my $status = $?;
$debug && print "waitpid returned status [$status]\n";

if (defined($err)) {
$debug && print " returning error\n";
return (0, $err);
}

$debug && print " returning success\n";
return (1, undef);
}
 
R

ru

oops -- I forgot to mention perl version, platform, etc. sorry.

The platform is SLES9:
Linux dbnu02a 2.6.5-7.257-smp #1 SMP Mon May 15 14:14:14 UTC 2006
x86_64 x86_64 x86_64 GNU/Linux

% perl -V
Summary of my perl5 (revision 5.0 version 8 subversion 3)
configuration:
Platform:
osname=linux, osvers=2.6.5, archname=x86_64-linux-thread-multi
uname='linux mahler 2.6.5 #1 smp thu aug 25 06:20:45 utc 2005
x86_64 x86_64 x86_64 gnulinux '
config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr
-Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm
-Duseshrplib=true -Doptimize=-O2 -fmessage-length=0 -Wall -Wall -pipe'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define
usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=define use64bitall=define uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS
-fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2 -fmessage-length=0 -Wall -Wall -pipe',
cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS
-fno-strict-aliasing'
ccversion='', gccversion='3.3.3 (SuSE Linux)', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib64'
libpth=/lib64 /usr/lib64 /usr/local/lib64
libs=-lm -ldl -lcrypt -lpthread
perllibs=-lm -ldl -lcrypt -lpthread
libc=/lib64//lib64/libc.so.6, so=so, useshrplib=true,
libperl=libperl.so
gnulibc_version='2.3.3'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic
-Wl,-rpath,/usr/lib/perl5/5.8.3/x86_64-linux-thread-multi/CORE'
cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib64'


Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY USE_ITHREADS USE_64_BIT_INT
USE_64_BIT_ALL USE_LARGE_FILES PERL_IMPLICIT_CONTEXT
Locally applied patches:
SPRINTF0 - fixes for sprintf formatting issues - CVE-2005-3962
Built under linux
Compiled at Dec 17 2005 03:22:14
%ENV:
PERL5LIB="/some/path/common/perl5/lib/perl5/site_perl"
@INC:

/some/path/common/perl5/lib/perl5/site_perl/5.8.3/x86_64-linux-thread-multi
/some/path/common/perl5/lib/perl5/site_perl/5.8.3
/some/path/common/perl5/lib/perl5/site_perl
/usr/lib/perl5/5.8.3/x86_64-linux-thread-multi
/usr/lib/perl5/5.8.3
/usr/lib/perl5/site_perl/5.8.3/x86_64-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.3
/usr/lib/perl5/site_perl
/usr/lib/perl5/vendor_perl/5.8.3/x86_64-linux-thread-multi
/usr/lib/perl5/vendor_perl/5.8.3
/usr/lib/perl5/vendor_perl
 
S

Simon Andrews

r.u said:
Hi folks,
I'm flummuxed. I just can't get the function below to capture
the output from STDERR of a program (ploticus in case, but
anything that writes to STDERR will do) in $err. It always
arrives in $out. Any ideas???

Are you sure there's nothing in the arguments you're passing which cause
stderr to get redirected to stdout? That would be the most obvious
cause. The way you're reading also seems pretty complex (unnecessarily so).

Open3 is pretty straightforward to use. Just to show it works (with
ploticus even), try the following program:

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

my $pid = open3(\*WRITE,\*READ,\*ERR,"pl");

close (WRITE);

close (READ);

while (<ERR>) {
print "ERR: $_";
}

...gets me:

./open3.pl
ERR: pl: error 20: No -prefab or scriptfile specified on command line
ERR:
ERR: Usage: pl -prefab prefabname [parameters] ..or.. pl scriptfile
[options]
ERR: This build can produce: ps eps svg svgz x11 png
ERR:
ERR: ploticus 2.33-Jun'06 (unix) Copyright 1998-2006 Steve Grubb,
http://ploticus.sourceforge.net

...which looks like it's working.

Simon.
 
R

ru

Simon said:
Are you sure there's nothing in the arguments you're passing which cause
stderr to get redirected to stdout? That would be the most obvious
cause. The way you're reading also seems pretty complex (unnecessarily so).

i'm sure. but see below...
Open3 is pretty straightforward to use. Just to show it works (with
ploticus even), try the following program:

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

my $pid = open3(\*WRITE,\*READ,\*ERR,"pl");

close (WRITE);

close (READ);

while (<ERR>) {
print "ERR: $_";
}

..gets me:

./open3.pl
ERR: pl: error 20: No -prefab or scriptfile specified on command line
ERR:
ERR: Usage: pl -prefab prefabname [parameters] ..or.. pl scriptfile
[options]
ERR: This build can produce: ps eps svg svgz x11 png
ERR:
ERR: ploticus 2.33-Jun'06 (unix) Copyright 1998-2006 Steve Grubb,
http://ploticus.sourceforge.net

..which looks like it's working.

yep, yours works :)

If I take your script, and change your bareword filehandles to scalars,
it fails. It seems that
this behaviour is documented :( The manpage only specifies that
filehandles will be
autogenerated for stdin and stdout, but doesn't mention stderr :((( I
must've missed this
little quirk, god knows how...

thanks for your effort, nonetheless.

RU
 
D

DJ Stunks

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

my $pid = open3(\*WRITE,\*READ,\*ERR,"pl");

close (WRITE);

close (READ);

while (<ERR>) {
print "ERR: $_";
}

..gets me:

./open3.pl
ERR: pl: error 20: No -prefab or scriptfile specified on command line
ERR:
ERR: Usage: pl -prefab prefabname [parameters] ..or.. pl scriptfile
[options]
ERR: This build can produce: ps eps svg svgz x11 png
ERR:
ERR: ploticus 2.33-Jun'06 (unix) Copyright 1998-2006 Steve Grubb,
http://ploticus.sourceforge.net

..which looks like it's working.

yep, yours works :)

If I take your script, and change your bareword filehandles to scalars,
it fails.

I wondered about that when I first saw your post because I'd
experienced the same thing, but I was on Perl 5.6.0 then, which AFAIK,
didn't support lexical filehandles so I assumed that was why. maybe a
bug report is in order.

-jp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top