Take the 2-minute tour ×

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...


share|improve this question
Why don't you just avoid printing things you don't want printed? –  cjm Jun 21 '11 at 4:21
I am using cgi_png() which inevitably prints the graph –  Italics Jun 22 '11 at 13:30
Then use scalar_png instead. It returns the image that cgi_png would print (except for the CGI header). –  cjm Jun 22 '11 at 14:23
i shall try that.. thank you –  Italics Jun 24 '11 at 20:09
add comment

6 Answers

up vote 7 down vote accepted

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;

 # 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;

 # 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.

 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;
share|improve this answer
add comment

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;


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); };

share|improve this answer
In case it's not clear, everything is automatically put back to normal at the end of the block, no matter how the block is exited. –  ikegami Jun 21 '11 at 2:06
add comment

Read the documentation for open.

Search for "Here is a script that saves, redirects, and restores STDOUT and STDERR using various methods".

What you want to do is not close STDOUT, but rather redirect it to /dev/null temporarily.

share|improve this answer
add comment


 close STDOUT;

From the perl doc: http://perldoc.perl.org/functions/open.html You have a : after your close, don't do that. The open above should also work with jus

open STDOUT;

This thread in perl monks might help you too: http://www.perlmonks.org/?node_id=635010

share|improve this answer
add comment

I checked 2 ways:

  1. via select
  2. via *OLD_STDOUT = * STDOUT, and see they are not usable in common case.

The reason is these 2 approachs redirect STDOUT only if "print" or something else is used in a Perl Script. But if you use "system()" call or call subscript, their output got to standard STDOUT anyway =((.

My point of view, the indeed solution is to be:

#!/usr/bin/perl -w
my $file1 = "/tmp/out.txt";
my $file2 = "/tmp/err.txt";
open my $oldSTDOUT, ">&STDOUT";
open OLDERR, ">&",\*STDERR; 
open(STDOUT, ">$file1")  or print("Can't redirect stdout: to $file1 ");
open(STDERR, ">$file2")  or print("Can't redirect stderr: to $file2 ");
system("pwd"); # this output isn;t got to standard output too, that is right!
open STDOUT, ">>&", $oldSTDOUT;
open STDERR, ">>&OLDERR"; 

I checked this solution and it worked for me.

share|improve this answer
add comment

You can implement something to catch STDOUT like so:

sub stdout_of (&) {
    my $code = shift;

    local *STDOUT;
    open STDOUT, '>', \(my $stdout_string = '')
        or die "reopen STDOUT: $!";


    return $stdout_string;

And then use it like so:

my $stdout = stdout_of { print "hello world" };

Localizing the filehandle inside stdout_of() allows you to avoid the tricks of closing and re-opening STDOUT.

share|improve this answer
add comment

Your Answer


