use File::Temp qw( tempfile ); sub capture_output { my $target_fh = shift; my $temp_fh = tempfile(); my $temp_fd = fileno $temp_fh; local *SAVED; local *TARGET = $target_fh; open SAVED, ">&TARGET" or die "can't remember target"; open TARGET, ">&=$temp_fd" or die "can't redirect target"; my $saved_fh = *SAVED; return sub { seek $temp_fh, 0, 0 or die "can't seek"; # rewind my $captured_output = do { local $/; <$temp_fh> }; close $temp_fh or die "can't close temp file handle"; local (*SAVED, *TARGET) = ($saved_fh, $target_fh); open TARGET, ">&SAVED" or die "can't restore target"; close SAVED or die "can't close SAVED"; return $captured_output; } } #### print STDERR "before redirection\n"; my $recorder = capture_output(*STDERR); # start print STDERR "during redirection\n"; my $saved_output = $recorder->(); # stop print STDERR "after redirection\n"; print "Saved output = $saved_output"; #### before redirection after redirection Saved output = during redirection