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

This should be so simple, but I'm really struggling...

I have an install script (win2000) which asks a few questions, runs a few system() commands, produces output to stdout and stderr. I need everything that's printed to the screen to also go to a single file, retaining the order it's generated.

doing

perl scriptname.pl >outfile
redirects ALL output to the file, meaning my "where do you want to install this?" question isn't printed, thus the user has no idea what he's being asked.

Think I need something like UNIX's tee function, or even some software which captures everything in a DOS box.

Of course, the reason I'm here is that a pure Perl solution would be ideal. I can redirect STDOUT and STDERR to a file easily, but need to keep it all going to screen as well!

TIA

Replies are listed 'Best First'.
Re: Capturing all (and I mean all) output to a file
by gellyfish (Monsignor) on Jan 12, 2005 at 10:35 UTC

    I think you probably want to look at the module IO::Tee

    /J\

      Looks good...

      Only thing I can't do now is redirect STDERR to the $tee filehandle... Not sure if I've misinterpreted the IO::Tee instructions, or just have a poor grasp of IO operations!

      See test code here:

      use IO::Tee; use strict; my $tee = new IO::Tee(\*STDOUT, ">outfile.out"); #Test normal output print $tee "normal data\n"; #Test system commands my $cmdout = `dir /w`; print $tee $cmdout."\n"; #Check input questions work print $tee "Enter some data\n"; my $input = <>; print $tee $input; #Check stderr also goes to the file + screen. warn "Warning here\n";
        Isn't it possible to redirect/reopen STDERR to STDOUT _before_ you call new IO::Tee ?
Re: Capturing all (and I mean all) output to a file
by inman (Curate) on Jan 12, 2005 at 11:56 UTC
    The line perl scriptname.pl >outfile redirects STDOUT to the file. Anything written to STDERR is written to the screen.

    The standard file handles are numbered in windows as they are in UNIX. STDIN=0, STDOUT=1, STDERR=2. Try tying together STDOUT and STDERR on the command line as part of the redirection to a file. the following code illustrates the point.

    #! /usr/bin/perl -w # use strict; use warnings; print "Standard Out\n"; print STDERR "Standard Error\n";
    Run using the command line:
    myScript.pl >out.txt 2>&1

    If you are working with Windows but you need to use a Unix tool then most of them have been ported. Try Unix Utils from SourceForge http://unxutils.sourceforge.net/. The tee command is available for you to use.

      I used the following in the end, using tee.exe - thanks for your tip!

      $|++; open (STDERR, ">&STDOUT"); #stuff my $cmdout = `system command`; print $cmdout;

      And ran it using

      perl code.pl |tee outfile.txt
Re: Capturing all (and I mean all) output to a file
by PodMaster (Abbot) on Jan 12, 2005 at 10:37 UTC
    tee -> IO::Tee

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Capturing all (and I mean all) output to a file
by sasikumar (Monk) on Jan 12, 2005 at 10:43 UTC
    Ha

    If you hate installing Modules often then here are two shortcuts.

    The simple solution would be run all the system comman in the scriptname.pl with >outfile for first time and use >>outfile for all the remaining system commands.

    eg: system("ls -l >/tmp/temp.log")

    The other solution is use the help of backticks run all your commands as $ouput=`command` and write the variable $output to a standard file.


    Thanks
    SasiKumar

      If you hate installing Modules often then here are two shortcuts.

      If you hate installing modules, then maybe you shouldn't be using Perl :)

        If you hate installing modules, then maybe you shouldn't be using Perl :)

        This is the difference between perl and other languages. There are 100 ways to solve a problem.

        mutant i dont want to install modules for simpler reasons when there is a easy work around.

        Thanks
        SasiKumar
Re: Capturing all (and I mean all) output to a file
by blazar (Canon) on Jan 12, 2005 at 22:30 UTC
    Of course, the reason I'm here is that a pure Perl solution would be ideal. I can redirect STDOUT and STDERR to a file easily, but need to keep it all going to screen as well!
    Have you tried reading
    perldoc -q STDERR
    perldoc -q 'dup\(\)'
    
    ?
    A reply falls below the community's threshold of quality. You may see it by logging in.