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

I have two applications where I want the main application to receive the output from STDERR/STDOUT in real time (i.e. when data is printed) from the other application. However, it seems like the main application is waiting or is blocked so it cannot print simultaneously. Any suggestions?

The executed application

#!/usr/bin/perl use Process; $| = 1; print STDERR "Started ..!\n"; Process::createProcess('./printApplication'); print STDERR ".. Finished!\n";
The print application
#!/usr/bin/perl print STDERR " printing some text\n"; print STDERR " printing some text\n"; print STDERR " printing some text\n"; print STDERR " printing some text\n"; sleep 10;
The library that contains execute functionality
package Process; use strict; use warnings; use IO::Select; use IPC::Open3; sub createProcess ($) { my($path) = @_; my($selector, $pid, @ready, $fh, $line); $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $path); $selector = IO::Select->new(); $selector->add(*CMD_ERR, *CMD_OUT); while(@ready = $selector->can_read()) { foreach $fh (@ready) { if(fileno($fh) == fileno(CMD_ERR)) { $line = scalar <CMD_ERR>; if(defined $line) { print STDERR $line; } } else { $line = scalar <CMD_OUT>; if(defined $line) { print STDOUT $line; } } $selector->remove($fh) if eof($fh); } } waitpid($pid, 0); }
UPDATE: I want the main application to print out the output from the second application immediately.
Currently, it waits for the sleep function to finish, THEN prints.

Replies are listed 'Best First'.
Re: Autoflush not possible when sleep is used?
by almut (Canon) on Feb 06, 2009 at 10:29 UTC

    Maybe it helps if you enable autoflushing in the print application — just kinda guessing, though...

    #!/usr/bin/perl $| = 1; print STDERR " printing some text\n"; ... sleep 10;

    Update: actually, on second thought, autoflushing should not be required here anyway, as you're printing to STDERR (which already does autoflush (is unbuffered) by default). IOW, I suppose the problem lies elsewhere...

      since by default STDOUT is selected, setting $| = 1 shouldn't have an effect on printing to STDERR.

        yeah, you're right — I overlooked the STDERR...

      Could the problem perhaps be that I compare fileno to a descriptor which is not the one I want to find?
      In the IPC::Open3 manual it is written to either use a reference to a typeglob filehandle or scalars to filehandles.
Re: Autoflush not possible when sleep is used?
by JavaFan (Canon) on Feb 06, 2009 at 10:20 UTC
    It may help if you tell what the program does, and what you like the program to output instead.