http://qs321.pair.com?node_id=277321


in reply to reading output from another script

The other solutions listed here are better, but if you really want to do it in your perl script:

First way: ./script | ./monitor.pl
# monitor.pl while(<>) { if(/wantthis/) { dosomething($_); } if(/warning/) {dosomethingelse($_); } print; ## pass on the output }

Option 2 - run the program from perl
# monitor.pl open(INPUT, "./script |") or die $!; while(<INPUT>) { # same as above if(/regex/) { dosomething($_); } print; } close INPUT;

Yet another way: If the script itself is perl, have it monitor it's own output.
# adapted from Perl Cookbook sub filteroutput { return if my $pid = open(STDOUT, "|-"); die "cannot fork: $!" unless defined $pid; while(<STDIN>) { if(/regex/) { dosomething($_); } print; } exit; #exit forked monitoring process }
Now add filteroutput(); above the rest of the script's normal code. It's self-monitoring.

Replies are listed 'Best First'.
Re: Re: reading output from another script
by Octavian (Monk) on Jul 24, 2003 at 13:48 UTC
    I think I must not have done a good enough job explaining what my problem is, as most suggestions have been dealing with monitoring log files or how to send emails or how to still view the output while piping to perl. The problem I am having is a script is NOT writing to a log file, it is dumping its output to STDOUT. They want me to write a perl script that can either call their script or they will pipe their output to my perl script. There script never stops until it is killed, and the data pumps out pretty fast, about three lines per second. They want my script to watch the output as it comes out and send an email if it see's a certain event occur. I know how to send the email and all that, Its just when I created my array,
    @array= <STDIN>;
    the program would wait until it stopped recieving STDIN before it would process the array, so it wouldnt check the input as it was coming in. The above post seemed to help a bit. (doing a while loop on STDIN) cause it appears that it proccesses a chunk at a time, it looks to me like 50 lines or so at a time, but it still isn't line by line... I will continue to play with the above while loops to see if I can get something acceptable to them...
    Like I said, it dumps about 3 lines per second, so if it does infact do chunks of 50 or so at a time as it is getting it, that may be fine, we can just blame the lag on email ;)
      In that case, the code I included above is exactly what you want.

      As for 50 lines at a time - it's not really happening that way. The above loops will do things line by line as they are output. I bet it's just buffered output that is the problem.

      You may have to unbuffer the original script (if it's perl, use the same solution - if it's not perl, I'm not sure what you can do). However, if it normally produces even output, then just fix the monitor.pl script.

      You can unbuffer the output from your monitor.pl perl script with:
      $| = 1;
      or as an alternative
      use FileHandle; STDOUT->autoflush;
      This should produce smooth, line by line output, as it is generated by the original script.

      As a side note, I bet your email gets sent immediately, it is just the text output to the screen that is buffered.

      ~Jon
        good idea with the autoflush idea, however it doesnt appear to fix it. Here are my findings:
        I have a test program that dumps look-alike output to the screen for development of this script...I call it test...so I do a
        ./test |./monitor.pl
        For testing I have it dump 9 lines, sleep for a second, then dump 9 more, and so on...when I run it through the monitor script, about every 5 seconds it dumps a big chunk to the screen. if I reduce it to dump 1 line, sleep for 1..then it takes longer...not exact numbers here, but it looks like it dumps the same number of lines in big chunks, just it takes longer to do...prob about 30 seconds or so...I changed it to dump 1 line and then sleep for 10, and guess what....the monitor script is now taking FOREVER to dump anything....if it was just a matter of the screen not being able to catch up with it, I could understand, but why, if the perl script is handling it in real time, would it take so long for the print to come out?
        Its no big thing, the script they wanted me to monitor dumps so fast that it proccesses the chunk in about 5 seconds or so, so I dont NEED to have this riddle solved for me, but it is a big stumper for me and if anyone knows the answer to this new problem that would be cool ;)
Re: Re: reading output from another script
by Octavian (Monk) on Jul 24, 2003 at 16:32 UTC
    Thanks for your assistance folks, and this thread was accidently duplicated...they are playing with new security "features" around here and it took all day for me to get the question posted, the site kept timing out, so in amongst the time outs, one of em must have made it in and I didnt know it...I dont know who can clean it up, but either this one or the other thread can be removed.
    just putting STDIN in a while loop did the trick, I have by far a lower level of knowledge of perl than some of the brains around here, so I was totally focused on the array and then doing a foreach loop rather than a while loop.
    Thanks again!