Solved

PERL IPC Process Hangs - Need help reading STDERR & STDOUT

Posted on 2007-03-28
2
1,077 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying 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

Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
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…

730 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