danmcb has asked for the wisdom of the Perl Monks concerning the following question:

I have a file where I run a shell command into a pipe. It looks like this:

#!/usr/bin/perl -w use strict; use Net::SSH::Expect; use TestExt; use Data::Dumper; package Test; sub run { my $cmd = 'ls -al'; my $pid = open OUT, "$cmd |" or die "cannot fork: $!"; print "running \"$cmd\" (pid = $pid) ... \n"; my @a = <OUT>; print "closing ... \n"; close OUT or die "cannot close: $! $?"; print @a; } package main; my @a = Test->run(); print @a;

The reason for the package Test will become clear in a moment. Now, I do the same thing but with the run method in an external file. here it is:

package TestExt; sub run { my $cmd = 'ls -al'; my $pid = open OUT, "$cmd |" or die "cannot fork: $!"; print "running \"$cmd\" (pid = $pid) ... \n"; my @a = <OUT>; print "closing ... \n"; close OUT or die "cannot close: $! $?"; print @a; } 1;

Now change the call to "TestExt->run()" and things stop working. When "CLOSE" is called, you get "cannot close: No child processes -1" as an error.

Now, if I remove the "use Net::SSH::Expect", everything works fine, both ways.

This is on a CentOS system, with a standard perl 5.8.8. It seems like quite an odd interaction, (why would having the code in an external module affect things?) and I suspect that it is a bug in Net::SSH::Expect. But if anyone here has any ideas about this, or can verify it on other systems, I'd be very interested to hear them before I file a report. Of course, there could as well be some silly error in there that I have not spotted, too.

Replies are listed 'Best First'.
Re: odd interaction of Net::SSH::Expect and open
by salva (Canon) on Oct 16, 2007 at 13:32 UTC
    it's even worse:
    salva@tokio:/tmp$ perl bug.pl running "ls -al" (pid = 25963) ... closing ... cannot close: No child processes -1 at bug.pl line 17.
    But when I launch the script with strace to see what's happening at the OS level...
    salva@tokio:/tmp$ strace -f -o /tmp/out perl bug.pl running "ls -al" (pid = 25984) ... closing ... total 358 drwxrwxrwt 11 root root 600 2007-10-16 15:28 . drwxr-xr-x 24 root root 736 2007-07-17 11:58 .. -rw-r--r-- 1 salva salva 0 2007-10-16 13:54 bar -rw-r--r-- 1 salva salva 373 2007-10-16 15:28 bug.pl -rw-r--r-- 1 salva salva 26 2007-10-16 13:52 foo drwx------ 3 salva salva 72 2007-10-16 09:21 gconfd-salva ...
    It works!!!

    BTW, I am running Debian unstable and perl 5.8.8.

Re: odd interaction of Net::SSH::Expect and open
by almut (Canon) on Oct 16, 2007 at 14:42 UTC

    Not a complete explanation... but my suspicion is that it has to do with Net::SSH::Expect globally setting $SIG{CHLD}. At least I do get the same error when replacing the use Net::SSH::Expect; in your code with

    BEGIN { package Net::SSH::Expect; use POSIX qw(:signal_h WNOHANG); $SIG{CHLD} = \&reapChild; sub reapChild { do {} while waitpid(-1,WNOHANG) > 0; } }

    (which is extracted as is from Net::SSH::Expect)

    When I localize the handler

    local $SIG{CHLD} = \&reapChild;

    things do work for me... (i.e. there's no interaction any longer).

      Thanks for the replies, and the confirmation. I did wonder a bit if I was dreaming when I found this one. I guess it is pretty clear this is a N:S:E bug, so I reported it at http://rt.cpan.org/Public/Bug/Display.html?id=30054 .

        I fixed this today in version 1.07. The new package must be available in some hours. bnegrao