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

I want to run b.pl, where b.pl is:

select(STDERR);$|=1;select(STDOUT);$|=1; # autoflush print "This is the prompt: "; my $input = <STDIN>; print "done.\n";

This works:

select(STDERR);$|=1;select(STDOUT);$|=1; # autoflush $cmd = 'perl b.pl 2>&1'; system($cmd);

But I want to capture the output into a log file in addition to displaying it on the screen. This, annoyingly, does not show the prompt until after you press RETURN to an empty screen:

select(STDERR);$|=1;select(STDOUT);$|=1; # autoflush $cmd = 'perl b.pl 2>&1 |'; open(CMD, $cmd) or die "error: open '$cmd': $!\n"; while (<CMD>) { print } # and print to log file here too close(CMD);

This works:

select(STDERR);$|=1;select(STDOUT);$|=1; # autoflush $cmd = 'perl b.pl 2>&1 | tee -a logfile.txt'; system($cmd);

But I would prefer not to rely on the availability of tee command. Please help.

Replies are listed 'Best First'.
Re: Command output to screen and logfile buffering problem
by tedrek (Pilgrim) on May 28, 2003 at 01:53 UTC
    simple, don't use buffered IO, use sysread instead:
    select STDERR; $| = 1; select STDOUT; $| = 1; open(CMD, 'perl b.pl 2>&1|') or die $!; open(LOGFILE, '>', 'b.log') or die $!; my $input; while(sysread(CMD, $input, 1024)) { print $input; print LOGFILE $input; } close(CMD);

    just remember to always use sysread on CMD if you use it once

      Thanks. Works like a charm.