Solved

PERL IPC Process Hangs - Need help reading STDERR & STDOUT

Posted on 2007-03-28
2
1,073 Views
Last Modified: 2010-05-18
Hello,

I've been playing around with IPC::Open3 for a few days now, getting better at it, but still just guessing in the dark really since I fairly new to this stuff on the PERL side of things.  I am trying to use PsExec to send remote commands to remote hosts in succession via the open3 command, and capture the errors and output to check for success or failure, so I can report on the status of each script being executed.

Basically if I set the while <CATCHERR> statement to a closed loop with nothing inside, the script runs... BUT if try to read $_ inside the while <CATCHERR> {} statement block, the script hangs and does not return.  How do I properly redirect STDERR to a temporary file CATCHERR, and then read the contents of that file to check on the output of my  command?

foreach my $line (@lines) {

            if ($line =~ m/((^[\w\d:\\\_\-\.]{1,})$)/sim) {
                  $target = $2;
            } else {
                  $target = "";
            }

       $cmd = 'psexec \\\\'.$target.' -u '.$user.' -p '.$pass.' -n 45 -c -f "'.$datafolder.$batch.'" -e';

        local *CATCHOUT = IO::File->new_tmpfile;
        local *CATCHERR = IO::File->new_tmpfile;
        local *CATCHIN = IO::File->new_tmpfile;
        my $pid = open3(gensym, \*CATCHOUT, ">&CATCHERR", $cmd);

        while( <CATCHOUT> ) { }  # closed the block to make it run, but I want to read the output into an array

#              push (@output, $_);
#              if ($debug) {
#                    print $_."<br />\n";
#              }
#              }

      waitpid($pid, 0);
        seek CATCHERR, 0, 0;
        while( <CATCHERR> ) { } # this by itself works ok, returns properly, but I can't read the results

        # this is what causes the code to hang, having a read of $_ while inside the while <CATCHERR> block

        seek CATCHERR, 0, 0;
        while( <CATCHERR> ) { # this is closer to what I want, but fails to return, always hangs on 2nd attempt

              if ($_ =~ m/error code (\d{1,})/) {
                        $result = $1
                  } else {
                        $result = -1;
                  }

                  if ($_ =~ m/^[\w\d\s\W]{3,}$/im) {
                $lastline .= $_;
                if ($debug) {
                      print "lastline = ".$lastline."<br />\n";
                      print "\$_ = ".$_."<br />\n";
                      }
                  }
            }

} #end foreach @line


OK, if someone could please tell me how to properly redirect the STDERR & STDOUT to files, read the files into an array, and prevent the script from hanging in the process, I would be most appreciative.

Thanks in advance...
G
0
Comment
Question by:ghosting
2 Comments
 
LVL 8

Accepted Solution

by:
nedfine earned 500 total points
ID: 18813978
0
 

Author Comment

by:ghosting
ID: 18819957
OK,

I have been playing around with variations on a theme from your suggested link...

No luck...

I can redirect STDERR & STDOUT...  BUT the script exits before completing execution and I lose STDOUT all together after having redirected it once.  How do I selectively redirect STDOUT & STDERR to a file, then flush their contents, return control back to STDERR & STDOUT, so I can read that file in using a different file handle to check my results, and repeat this process many times?

Here's a stripped down version of my code after many revisions....

open (OUTPUT, ">output.txt") || die $!;
#open (INPUT, "input.txt")    || die $!;
open (ERROR, ">error.txt")   || die $!;

STDOUT->fdopen(\*OUTPUT, "w") || die $!;
#STDIN->fdopen(\*INPUT, "r")   || die $!;
STDERR->fdopen(\*ERROR, "w")  || die $!;


system ($cmd);

select (STDOUT);
#select (STDERR);
$| = 1;

close (OUTPUT);
close (ERROR);

The BIG problem is STDOUT & STDERR are not returning to their normal states, so my script simply says it's done, but keeps running without my knowing what's happening.  Please illuminate me on how to correct this code snippet so it will work for me...

Thanks in advance,
G
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question