Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can close and reopen STDOUT in Perl?

Tags:

stdout

cgi

perl

I'd like to close STDOUT to prevent my code from outputing a particular image that I need for further computation but do not want on my web page.

So i want to close STDOUT, do what I have to do with my code, then reopen STDOUT to output stuff to a web page. (Not to a file)

What I tried is:

    close STDOUT;
    # my code here
    open STDOUT;

This doesn't work...

Thanks

like image 260
Italics Avatar asked Jun 20 '11 20:06

Italics


People also ask

How do I close a STDOUT in Perl?

close(STDOUT); close(STDERR); open STDOUT, ">>&", $oldSTDOUT; open STDERR, ">>&OLDERR"; print "BUT THIS OUTPUT IS SEEN IN A STANDARD OUTPUT\n"; I checked this solution and it worked for me.

What is stderr Perl?

In Perl, when a perl program starts, these two output channels are represented by two symbols: STDOUT represents the Standard Output, and STDERR represents the Standard Error.

How do I redirect a file in Perl?

Redirect STDOUT using a filehandle As with select, this will have a global affect on the Perl program. use feature qw/say/; use autodie; # copy STDOUT to another filehandle open (my $STDOLD, '>&', STDOUT); # redirect STDOUT to log. txt open (STDOUT, '>>', 'log. txt'); say 'This should be logged.


2 Answers

There are several ways to approach your problem, and many of them do not require you to close STDOUT and risk fubaring your program's standard I/O channels.

For example, you can use the (1-arg) select command to direct the output of print commands somewhere else temporarily.

 print $stuff_you_want_to_send_to_STDOUT;

 select(NOT_STDOUT);
 # now default print sends things to NOT_STDOUT.
 # This doesn't need to be a real filehandle, though you may get warning
 # messages if it is not.
 ...;
 print $the_image_you_dont_want_to_go_to_STDOUT;
 ...;

 select(STDOUT);
 # now  print  sends things to STDOUT agin
 print $more_stuff_you_do_want_to_go_to_STDOUT;

You can also reassign the *STDOUT glob at run-time without closing any handles.

 *OLD_STDOUT = *STDOUT;
 print $for_STDOUT;

 *STDOUT = *NOT_STDOUT;     # again, doesn't need to be a real filehandle
 print $stuff_to_suppress;

 *STDOUT = *OLD_STDOUT;     # restore original STDOUT
 print $more_stuff_for_STDOUT;
like image 169
mob Avatar answered Nov 16 '22 00:11

mob


It's bad to close STDOUT since much assumes it's always open. It's better to redirect it to /dev/null (unix) or nul (Windows).

If you want to redirect the file descriptor,

use Sub::ScopeFinalizer qw( scope_finalizer );

{
    open(my $backup_fh, '>&', \*STDOUT) or die $!;
    my $guard = scope_finalizer { open(STDOUT, '>&', $backup_fh) or die $!; };
    open(STDOUT, '>', '/dev/null') or die $!;

    ...
}

If you just want to redirect STDOUT,

{
    local *STDOUT;
    open(STDOUT, '>', '/dev/null') or die $!;

    ...
}

If you just want to redirect the default output handle,

use Sub::ScopeFinalizer qw( scope_finalizer );

{
    open(my $null_fh, '>', '/dev/null') or die $!;
    my $backup_fh = select($null_fh);
    my $guard = scope_finalizer { select($backup_fh); };

    ...
}
like image 31
ikegami Avatar answered Nov 16 '22 01:11

ikegami