Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Print STDOUT and STDERR to file and to screen

by Noame (Beadle)
on Aug 02, 2009 at 19:13 UTC ( #785270=perlquestion: print w/ replies, xml ) Need Help??
Noame has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

Iím writing a Perl script which should run (by detention) as stand alone mean without calling to external Perl modules (I Canít use external modules like: File::Tee, IO::Tee and so on).
The program should be run on WIN and UNIX machine as well (Perl ).
I would like to print the STDOUT & STDERR handlers to log file and to the screen parallels.
If the program failed then the error message should be print in the log file and the console as well.
Iíve written the code below:
my $LOG_FILE = "$HOME/log/test.txt"; open(LOG, "> $LOG_FILE") || die "Can't redirect stdout"; open (CMD, "ls |"); while (<CMD>) { lprint ($_) } close(CMD); sub lprint () { my ($line) = @_; print LOG $line; print $line; }
The codes above prints the STDOUT to log file and to the screen as I need!!!
But how can I control the STDERR handler?
For example - If I change the CMD command in order to get an error message:
From: open (CMD, "ls |"); To: open (CMD, "ls_non_command |");
Then I should fail and get an error message - I want to print the error message to the log file and to the screen.

Please advice.

Comment on Print STDOUT and STDERR to file and to screen
Select or Download Code
Re: Print STDOUT and STDERR to file and to screen
by jbt (Chaplain) on Aug 02, 2009 at 19:28 UTC
    Given any cmd:
    open(CMD, "cmd 2>&1 |");
      This/that won't do what the OP requested since all it does is to force STDERR onto STDOUT - it doesn't satisfy the requirement to send to both file and screen in parallel.

      A user level that continues to overstate my experience :-))
Re: Print STDOUT and STDERR to file and to screen
by afoken (Parson) on Aug 02, 2009 at 20:02 UTC

    Why do you post exactly the same problem twice? Print STDOUT and STDERR to file and to console has a lot of useful answers.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Print STDOUT and STDERR to file and to screen
by trwww (Priest) on Aug 02, 2009 at 21:06 UTC

    I Canít use external modules like: File::Tee, IO::Tee and so on

    Whenever I hear someone say this, big red flags go up.

    The module itself looks to be about 100 lines of code in a single file so I'm having a really hard time understanding what it is that could be keeping one from using it.

      This is common in financial and defence installations that do not allow downloads. Controlled downloads are done under quarantine and thoroughly tested - a beauracratic process which takes time and written justification. An uncontrolled download could be a sackable offence.
        That doesn't apply here.

        Definitely doesn't apply here. What is the difference between coping the code from Perl Monks and copying from CPAN? None. Except for that in this case you're going to get better, easier to use code from CPAN.

        I've been doing this a long time, and when I hear someone say "I can't use a module", what they really are saying is "I don't know how to use a module".

Re: Print STDOUT and STDERR to file and to screen
by Bloodnok (Vicar) on Aug 02, 2009 at 22:54 UTC
    Hmmm, I'm interested as to the difference in the manner with which you treat the calls to open ... when open'ing the file you check for failure, but you fail (pun intended) so to do with the command.

    I think you'll find that your requirement will be met if you chose to do so i.e.

    open CMD, "some_command |" or lprint("Command: some_command failed - $ +!"), exit 1;

    A user level that continues to overstate my experience :-))
Re: Print STDOUT and STDERR to file and to screen
by Khen1950fx (Canon) on Aug 03, 2009 at 02:00 UTC
    Try this. It's sending STDOUT to log or STDERR to log if there's an error:

    #!/usr/bin/perl use strict; use warnings; use diagnostics; open(LOG, '>', 'LOG_FILE') or die "Can't redirect stdout: $!"; open(CMD, 'ls |'); open(STDERR, '>&', STDOUT) or die "Can't redirect stderr: $!"; open(STDERR, '>', 'LOG_FILE') or die "Can't redirect stderr: $!"; print "LOG_FILE\n"; while (<CMD>) { &lprint ($_) } sub lprint { my ($line) = @_; print LOG $line; print $line; } close(CMD) or die "close CMD failed: $!"; exit(1);
    Update: Fixed a typo
      Thanks a lot - that what i need.

        Can you not simply redirect STDERR / STDOUT?
        This example (from the camel i think) redirects errors into a FH and to stdout. so you still get them on screen and in a logfile. You would only then need to rediirect STDOUT as shown above?

        sub make_log{ # make a log file my $log = shift; # open the log and stamp it open (my $log_file, '>>', $log) || die "Failed to open $log:\n$!"; print $log_file "\n------> log for $0\n------> ".scalar(localtime) +."\n\n"; # make sure errors are put into the logfile # i.e. print STDERR "weird" ~ not in logfile # warn "freaky" ~ in logfile (and the screen) # die "AAaaarrrrrgh!" ~ in logfile $SIG{__WARN__} = sub {print $log_file @_;print STDOUT @_}; $SIG{__DIE__} = sub {print $log_file @_;print STDOUT @_;exit 1}; # return complete return $log_file; }
        Just a something something...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://785270]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2014-12-27 10:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls