|
Posted by Ronny on May 5, 2008, 9:12 am
Please log in for more thread options
I try to use the program below to catch standard output and standard
error
of a process. The program itself runs well, and it *does* write at
least to
standard output, but in the code below, the line saying "### READING"
is never printed and @msg is still empty afterwards. This means that
$selector->can_read() must have returned false already the first time
it was called. Any suggestion on what could I have done wrong here?
my @msg;
my $pid=open3(*CMD_IN,*CMD_OUT,*CMD_ERR,@cmd)
or confess "Open3 error: $!\n";;
$SIG = sub {
waitpid($pid,0)>0 &&
print "SIGCHILD status=$? pid=$pid\n";
};
my $selector=IO::Select->new();
$selector->add(*CMD_ERR,*CMD_OUT);
while(my @ready=$selector->can_read()) {
foreach my $fh (@ready) {
print "### READING\n";
push @msg,scalar(<$fh>);
$selector->remove($fh) if eof($fh);
}
}
close CMD_OUT;
close CMD_ERR;
|
|
Posted by Ben Morrow on May 5, 2008, 6:55 pm
Please log in for more thread options
> I try to use the program below to catch standard output and standard
> error of a process. The program itself runs well, and it *does* write
> at least to standard output, but in the code below, the line saying
> "### READING" is never printed and @msg is still empty afterwards.
> This means that $selector->can_read() must have returned false already
> the first time it was called. Any suggestion on what could I have done
> wrong here?
Works for me here (i686-freebsd). What platform are you on, and what
command are you trying to run? In general, if you can provide a complete
program people can copy/paste/run, you're more likely to get help: in
this case, you omitted the 'use' lines and the contents of @cmd.
> my @msg;
> my $pid=open3(*CMD_IN,*CMD_OUT,*CMD_ERR,@cmd)
> or confess "Open3 error: $!\n";;
I would normally say 'Use lexical filehandles!' at this point;
unfortunately, IPC::Open3 was written before they existed and the
obvious way
my $pid = open3(my $CMD_IN, my $CMD_OUT, my $CMD_ERR, @cmd)...
doesn't work (and can't be made to since undef is already meaningful).
So you have to fall back to the old method of using Symbol::gensym:
use Symbol qw/gensym/;
my ($CMD_IN, $CMD_OUT, $CMD_ERR) = (gensym, gensym, gensym);
my $pid = open3($CMD_IN, $CMD_OUT, $CMD_ERR, @cmd)...
which is definitely ugly, but IMHO worth it (if you must use IPC::Open3
at all: I'd use IPC::Run instead). For one thing, these gensymmed
filehandles close when they go out of scope, just like more usual
lexical filehandles. Of course, I'd use a hash to hold the filehandles:
my %CMD = map {($_, gensym)} qw/IN OUT ERR/;
my $pid = open3(@CMD{qw/IN OUT ERR/}, @cmd)...
> $SIG = sub {
> waitpid($pid,0)>0 &&
> print "SIGCHILD status=$? pid=$pid\n";
> };
> my $selector=IO::Select->new();
> $selector->add(*CMD_ERR,*CMD_OUT);
> while(my @ready=$selector->can_read()) {
> foreach my $fh (@ready) {
> print "### READING\n";
> push @msg,scalar(<$fh>);
> $selector->remove($fh) if eof($fh);
Using eof is nearly always a mistake: it's almost always better to check
the return value of your read statement instead. Something like
my $msg = <$fh>;
defined $msg
? push @msg, $msg
: $selector->remove($fh);
This also means you don't get a spurious undef on the end of @msg.
Ben
--
I must not fear. Fear is the mind-killer. I will face my fear and
I will let it pass through me. When the fear is gone there will be
nothing. Only I will remain.
ben@morrow.me.uk Frank Herbert, 'Dune'
|
|
Posted by Ilya Zakharevich on May 5, 2008, 8:26 pm
Please log in for more thread options [A complimentary Cc of this posting was NOT [per weedlist] sent to
Ben Morrow
> I would normally say 'Use lexical filehandles!' at this point;
> unfortunately, IPC::Open3 was written before they existed and the
> obvious way
>
> my $pid = open3(my $CMD_IN, my $CMD_OUT, my $CMD_ERR, @cmd)...
>
> doesn't work (and can't be made to since undef is already meaningful).
I have no idea what you mean here.
sub open3 ($$$$@) {
$_[0] = IO::Handle->new unless defined $_[0]; # Or whatever is THE
initializer
...
}
Yours,
Ilya
|
|
Posted by Ben Morrow on May 6, 2008, 12:00 pm
Please log in for more thread options
> [A complimentary Cc of this posting was NOT [per weedlist] sent to
> Ben Morrow
> > I would normally say 'Use lexical filehandles!' at this point;
> > unfortunately, IPC::Open3 was written before they existed and the
> > obvious way
> >
> > my $pid = open3(my $CMD_IN, my $CMD_OUT, my $CMD_ERR, @cmd)...
> >
> > doesn't work (and can't be made to since undef is already meaningful).
>
> I have no idea what you mean here.
>
> sub open3 ($$$$@) {
> $_[0] = IO::Handle->new unless defined $_[0]; # Or whatever is THE
> initializer
> ...
> }
Yeah, in general you can do that; however, for the specific case of
open3, the docs say
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.
so at least the CHLD_ERR filehandle can't be autovivified. Presumably it
is felt that this behaviour can't be changed.
Ben
--
"If a book is worth reading when you are six, * ben@morrow.me.uk
it is worth reading when you are sixty." [C.S.Lewis]
|
|
Posted by Ilya Zakharevich on May 6, 2008, 8:04 pm
Please log in for more thread options [A complimentary Cc of this posting was NOT [per weedlist] sent to
Ben Morrow
> > sub open3 ($$$$@) {
> > $_[0] = IO::Handle->new unless defined $_[0]; # Or whatever is THE
> > initializer
> > ...
> > }
> Yeah, in general you can do that; however, for the specific case of
> open3, the docs say
>
> 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.
Thanks, I forgot about this semantic. Which does not mean that one
could not write ALSO open3_autovivify... ;-)
Yours,
Ilya
|
| Similar Threads | Posted | | IPC::Open3 | August 24, 2005, 2:23 pm |
| IPC::Open3 | November 11, 2006, 8:10 pm |
| How do you use IPC::Open3.... | January 19, 2008, 5:11 pm |
| open3 and signals | September 20, 2004, 8:43 pm |
| IPC::Open3 issue | August 24, 2005, 3:21 pm |
| can't get STDERR using open3... | December 20, 2006, 3:21 pm |
| IPC::open3: What goes wrong? | August 1, 2007, 1:05 pm |
| Example for open3 on windows? | May 20, 2008, 1:33 am |
| Open3 with nonblocking reads | September 3, 2004, 7:51 am |
| IPC::Open3 and the error filehandle | October 26, 2007, 9:33 am |
|