jayashreerajendran
jayashreerajendran

Reputation: 31

How to redirect output of some commands to a file but keep some in the console?

I am using below perl script,

open (STDOUT, '>',"log.txt")|| die "ERROR: opening log.txt\n";
print "\n inside";
close (STDOUT);
print "\noutside";

I need string "inside" need to be printed inside log.txt. string "outside" need to be printed in the console.

But with my script string "inside" is printed inside log.txt, but string "outside" is not printed on the console.

Can anyone help me on this

Upvotes: 1

Views: 534

Answers (1)

zdim
zdim

Reputation: 66891

You redirect the standard output stream to a file with open STDOUT, '>', $file. After that there is no simple way to print to the console.

Some ways to print to both a file and the console

  • Save STDOUT before redirecting and restore it later when needed. Again, see open

    open SAVEOUT, ">&STDOUT"  or warn "Can't dup STDOUT: $!";
    open *STDOUT, ">", $logfile or warn "Can't redirect STDOUT to $logfile: $!";
    say "goes to file"; 
    ...
    open STDOUT, ">&SAVEOUT"  or warn "Can't reopen STDOUT: $!";  # restore
    say "goes to console";
    
  • Print to a variable what you intend for console; use select to switch the default for where prints go

    open my $fh_so, '>', \my $for_stdout;
    select $fh_so;
    say "goes to variable \$for_stdout";
    say STDOUT "goes to console";
    ...
    select STDOUT;    # make STDOUT default again
    say $for_stdout;  # goes to console (all accumulated $fh_so prints)
    

    With this you can reach the console by specifying STDOUT, otherwise you would put out all STDOUT-intended prints once you select back to STDOUT

  • Print logs to a file directly, as in Jens's answer

    open my $fh_log, '>', $logfile or die "Can't open $logfile: $!";
    say $fh_log "goes to $logfile";
    say         "goes to console";
    ...
    close $fh_log;
    

    where the default print (or rather say above) keeps going to the console

The first two seem a little cumbersome, don't they. I'd recommend to print logs directly to a log file, unless STDOUT needs to be redirected for the most of the program, or you have a compelling reason to select filehandles around.

For say, which adds newline to what is printed, you need use feature 'say'; at the beginning.

Always start your programs with use warnings; and use strict;.

Upvotes: 2

Related Questions