in reply to How to print called program to stdout

To clarify I (from what I've learned at this point) that perhaps the best way is to just capture the output of the subprogram when it is called from the main program then just print it out from main when it returns. However, I'd like to see the printout of the test results as the subprogram runs, so that I know something failed at that moment instead of having to wait until the entire test subprogram completes to gather my results?
  • Comment on Re: How to print called program to stdout

Replies are listed 'Best First'.
Re^2: How to print called program to stdout
by TorontoJim (Beadle) on Mar 18, 2016 at 20:01 UTC

    This may not be what you're looking for, but when I'm testing a script, I redirect STDERR to print to STDOUT. That way I can pepper my script with print statements to see what is going on so that I can debug it. This is how I do it:

    BEGIN { $| = 1; open(STDERR, ">&STDOUT"); print "Content-type: text/html\n\n"; }

    Hope that assists you.

Re^2: How to print called program to stdout
by Marshall (Canon) on Mar 18, 2016 at 22:45 UTC
    $| =1; is a key thing.

    What $| =1; does is un-buffer STDOUT. STDERR is already un-buffered by default.

    What buffering does is to gather up stuff until it reaches a "quanta" of stuff to write. Then the O/S writes it all at once. This difference matters a lot in terms of performance. For writing to a HD, maybe 4Kbytes or 8Kbytes might be the "quanta" for stdout.

    When $|=1 is in effect, each print statement will actually access the HD for every print.

    Note that you can redirect stdout and stderr individually from the command line. The default is only re-direct stdout, "someprog >stdoutfile"."command > combinedfile 2>&1" re-directs both std-err and std-out to the same file.

    For some programs that run for a long time on the command line, I use stderr to print status, "working on X..". I do that so that I can see that the program is not "hung". And I send any actual error to both stderr and stdout.

    I think that all you need to do is set: $|=1; When you do that, the "errors" and the "output" will occur together on the stdout console. When you have the program working, then take $|=1; out if you want it to run faster. $|=1 eliminates the delay between an error and the next stdout line, also stdout lines appear in "real time" instead of there being a delay. It is certainly possible that if the "buffering write quanta" is not fulfilled, that the program doesn't print anything until it actually has already exited!

      I only use that on web servers. I want it to print back to the output so I can see the results in the browser. I never use it on my local machine.

        Then how does your "main program" call the "subprogram" during the test -- how is your test script interfacing with the webserver? Is the "main program" also on the webserver, and if so, is it calling the "subprogram" as a function call, or thru a system() or `` access, or something else? Or is the "main program" on your local machine, accesssing the webserver "subprogram" via LWP::Simple? Or something else entirely?

        Since it's printing to STDOUT to the web browser, are you sure you've not accidentally embedded the "subprogram" output inside something hidden in the HTML? Could it be inside a comment, accidentally inside a tag, or in a non-displayed element? (view-source is your friend when a CGI's output is not where you think it should be).

Re^2: How to print called program to stdout
by pryrt (Abbot) on Mar 19, 2016 at 00:06 UTC

    There are some details that would help make it easier to answer your questions. 1) What is the form of the output from your subprograms? (ie, Do they print to STDOUT or STDERR, or do they just return a value?). 2) How are you calling the subprograms from your main program? (ie, as direct function/method calls, or by system() calls or qx// or ``).

    Because if your subprograms are just printing to STDOUT, and you are calling them from your main program via function/method calls, it surprises me that you cannot see their output. But if you are calling a separate process (which your use of "program" rather than "function" or "method" might indicate) using a system() call, then you are going to have to switch to a print `subprogram` paradigm, otherwise the separate process's output will be lost to the system()'s ether.

    Update: Specifically, if your mainprogram.pl looks like:

    #!perl use warnings; use strict; use MyModuleToBeTested; callSomeFunctionThatPrintsToSTDOUT();
    ... then i don't see why it wouldn't print.

    OTOH,

    #!perl use warnings; use strict;
    system("callSomeProgram");
    print `runASecondProgram`;
    ... will not print anything from "callSomeProgram", because system() doesn't output, whereas it will print the STDOUT from "runASecondProgram" because of your print statement.

    edit: strikeout patently false info and fix typos from the fix. Thanks choroba

      > because system() doesn't output

      It does. system prints to STDOUT, you just can't access its output from the calling Perl program:

      $ perl -we 'system "date"' Sat Mar 19 10:48:46 CET 2016
      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        oops, you're right (struck out)

        What I really should have been pointing out is that without the print statement, `` or qx// wouldn't output anything.