Temporarily hijacking STDOUT

J

John

I'm using Spreadsheet::parseExcel via an example program, xls2txt.pl

xls2txt.pl turns an Excel file into text and pumps the text out with
print statements, sending it to STDOUT.

Without changing the original, I want to pump the text to an
intermediate file, then start with my own code to massage the text with
regexes, do some table lookups and send the results to a third and
fourth file.

Before calling the example code, I did:

open STDOUT, ">$scratch_file";

This successfully gave me my scratch file.
Now when I start my own suspect manipulations, I wanna resume printing
to the screen.

I tried ...

open STDOUT, ">/dev/console";

.... and while it didn't error out, I didn't see any of my subsequent
diagnostic text.

I take it I'm opening the wrong device.

Is there a proper way to do this?

Was thinking there was a way to query for a file object originally
associated with STDOUT, to save a pointer to that, and reassign it
later. But that's vague C-influenced thinking and terminology--I don't
know how I'd translate it to a CPAN or Google search.

If this is impossible -- or an egregious breach of Perl etiquette -- I
suppose I can make my own version of xls2txt. But I'm nonetheless
curious, and lazy.

John Campbell
 
P

Paul Lalli

John said:
Without changing the original, I want to pump the text to an
intermediate file, then start with my own code to massage the text with
regexes, do some table lookups and send the results to a third and
fourth file.

Before calling the example code, I did:

open STDOUT, ">$scratch_file";

This successfully gave me my scratch file.
Now when I start my own suspect manipulations, I wanna resume printing
to the screen.

I tried ...

open STDOUT, ">/dev/console";

... and while it didn't error out, I didn't see any of my subsequent
diagnostic text.

I take it I'm opening the wrong device.

No need for assumptions. Ask Perl if or why the open failed:
open STDOUT, '>', '/dev/console' or die "Cannot set STDOUT to
/dev/console: $!";

Regardless, I don't see any reason to specify the "original" STDOUT
explicitly at all. Just localize your changes:

$ cat clpm.pl
#!/usr/bin/perl
use strict;
use warnings;

print "Sent to STDOUT\n";
{
local *STDOUT;
open STDOUT, '>', 'outfile.txt' or die "Could not redirect STDOUT:
$!";
print "Sent to file\n";
}
print "Sent to STDOUT again.\n";

__END__

$ ./clpm.pl
Sent to STDOUT
Sent to STDOUT again.
$ cat outfile.txt
Sent to file
$


Paul Lalli
 
J

John

Thanks Paul.

Also, I apologize for the hasty post.

I found an earlier solution in this group under:
"newbie q: Reassign STDOUT/ERR in DOS"

Even though I'm not using DOS, that advice was valid, though your
solution is more concise.
 
X

xhoster

John said:
I'm using Spreadsheet::parseExcel via an example program, xls2txt.pl

xls2txt.pl turns an Excel file into text and pumps the text out with
print statements, sending it to STDOUT.

Without changing the original,

Without changing the original what?
I want to pump the text to an
intermediate file, then start with my own code to massage the text with
regexes, do some table lookups and send the results to a third and
fourth file.

Before calling the example code, I did:

open STDOUT, ">$scratch_file";

Rather than opening and reopening file handles, I'd just change which
handle is the default.

open SCRATCH_FH, ">$scratch_file" or die $!;
select SCRATCH_FH;

# whatever your code is
# (which does unadorned print statements)
# goes here.

select STDOUT;

Xho
 
J

John

Xho wrote:

"Without changing the original what?"

Oops. Without changing the original, borrowed code of xls2txt.pl

And:
"Rather than opening and reopening file handles, I'd just change which
handle is the default."

Another snazzy way to do it. I'd actually read about default and select
before posting and for some reason failed to see that it applied to me.
In your post, it makes perfect sense.

A loose end from Paul's post:

Ask Perl if or why the open failed:
open STDOUT, '>', '/dev/console' or die "Cannot set STDOUT to
/dev/console: $!";

Now I'm curious enough to roll back and try this.
No, I didn't even ask Perl *if* the open failed; I figured the output
was around somewhere, just not where I was looking.
 
U

usenet

You can redirect any filehandle (including STDOUT) to any other
filehandle like this:

*STDOUT = *OUT;

This presumes, of course, that you have already opened OUT...

Cheers!
 
R

Randal L. Schwartz

John> Before calling the example code, I did:

John> open STDOUT, ">$scratch_file";

John> This successfully gave me my scratch file.
John> Now when I start my own suspect manipulations, I wanna resume printing
John> to the screen.

John> I tried ...

John> open STDOUT, ">/dev/console";

John> ... and while it didn't error out, I didn't see any of my subsequent
John> diagnostic text.

John> I take it I'm opening the wrong device.

John> Is there a proper way to do this?

If you *don't* fork, you can get away with this:

{
local *STDOUT;
open STDOUT, ">newplace" or die;
...
}

However, that doesn't make this particular STDOUT be fd 1, so forked
processes won't be writing there. They'll see the old place instead.

print "Just another Perl hacker,"; # the original
 
J

John

Thanks guys. All three approaches worked just fine.

No forks,Randal. This is big-iron, batch-process logic going on here.
Nothing fancy.
Though the rightful heir to a batch process would, I suppose, be a
shell script, I can't be platform specific.

Another argument against the '/dev/console' dodge.

By the way Paul, on further review, that open did not fail as far as
Perl was concerned.
But it certainly wasn't useful to me. Wonder where those words went...

If anyone else is mildly curious about that, I'm running Perl from a
command line on Mac OS X 10.3.9.

Thanks again,

John Campbell
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top