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

unless ($I="unworthy scum") {give_aid(%much_knowledge)}
I have two scripts that take input from the user and print info to the screen. I would like to create a script that calls those other two and logs everything (at least what the user sees on the screen) to a file.

So far, all of my attempts have failed.

Replies are listed 'Best First'.
Re: logging STDOUT of multiple scripts
by Cubes (Pilgrim) on Jul 31, 2001 at 03:19 UTC
    You could do it in perl, but you might find it easier to just use something already on most (all?) *ix systems:
    somecommand 2>&1 | tee logfile
    Try man tee for more information.

    update: I realized this answer is a bit terse and doesn't really answer the question. If you are actually looking for how to do it in perl, you will have to intercept output from the scripts (send that both to a file and to STDOUT), and the user's input, which will have to be passed along to the script. This can get tricky, expecially if your program doesn't know what should happen next (should it look for output from the script you just ran, or input from the user next?), but IPC::open2/open3 or Expect.pm can do what you want.

Re: logging STDOUT of multiple scripts
by RhetTbull (Curate) on Jul 31, 2001 at 16:53 UTC
    You might want to take a look at Filter::Handle. It will let you use a sub to process STDOUT (or any other file handle) so you can log it to a file and then send it to the screen.
Re: logging STDOUT of multiple scripts
by Monky Python (Scribe) on Jul 31, 2001 at 21:48 UTC
    I don't know if the following code is the correct solution for your problem because it does not handle any (interactive) user input (besides it's just a quick hack -- without error handling).

    Short Description:
    ------------------
    - open a pipe to each given process (@ARGV) 8|
    - poll each pipe for new data (optionally print data)
    - finished if each filehandle returns eof

    #!/usr/local/bin/perl -w use strict; use IO::File; my $count = 0; my @fdesc = (); my %fdname; # create pipes foreach my $prog (@ARGV) { my $fh = IO::File->new("$prog |"); push(@fdesc, $fh); $fdname{$fh} = $prog; } # listen my $notDone=0; do { $notDone=0; foreach my $fh (@fdesc) { if (!$fh->eof()) { $notDone=1; print "<",$fdname{$fh},">: ",$fh->getline(); } } } while ($notDone);
    example usage: combineLog.pl ls "ps auxw" "du -sk ~*" > comb.log 2>&1

    MP