|
Posted by Brian Helterlilne on June 26, 2008, 7:53 pm
Please log in for more thread options
Keith Thompson wrote:
> I want to redirect STDOUT to a file, and have the redirection apply to
> any programs that I invoke. Here's a brief outline of what I'm doing
> (full sources to follow):
>
> open SAVE_STDOUT, '>&STDOUT' or die "SAVE_STDOUT: $!\n";
> open STDOUT, '>', 'log.txt';
> system "some_command";
> close STDOUT;
> open STDOUT, '>&SAVE_STDOUT' or die "Restoring STDOUT: $!\n";
>
> The invoked command itself invokes another command. I want to collect
> the standard output of both commands in a single file. (I also want
> to redirect stderr, but I'm leaving that out for now.)
>
> Under Cygwin (Perl 5.8.8) and Linux (Perl 5.8.0), it works fine.
>
> Under Windows XP (ActiveState Perl 5.6.1), the output of the invoked
> command is properly redirected to the file, but the output of the
> inner command is just lost, though I've confirmed that it is executed.
>
> Any suggestions? (Upgrading ActiveState Perl is not currently an
> option, but it would be nice to know if a newer version fixes this.)
>
> I'm using 3 Perl programs, called "outer.pl", "middle.pl", and
> "inner.pl" (the ".pl" suffix is needed to make Windows recognize that
> these are Perl scripts).
>
> ===== outer.pl =====
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> print "Running on $^O\n";
>
> my $prefix;
> if ($^O =~ /^mswin/i) {
> $prefix = '.\';
$prefix = 'perl .\';
> }
> else {
> $prefix = './';
> }
>
> print "Begin outer\n";
>
> open SAVE_STDOUT, '>&STDOUT' or die "SAVE_STDOUT: $!\n";
> print SAVE_STDOUT if 0; # avoid "used only once" warning
>
> open STDOUT, '>', 'log.txt';
>
> print "outer calling middle\n";
> system "$middle.pl";
> print "outer after middle\n";
>
> close STDOUT;
> open STDOUT, '>&SAVE_STDOUT' or die "Restoring STDOUT: $!\n";
>
> print "End outer\n";
>
> open my $OUTER_LOG, '>', 'outer.log';
> print $OUTER_LOG "outer, pid=$$\n";
> close $OUTER_LOG;
> ===== end outer.pl =====
>
> ===== middle.pl =====
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> my $prefix;
> if ($^O =~ /^mswin/i) {
> $prefix = '.\';
$prefix = 'perl .\';
> }
> else {
> $prefix = './';
> }
> print "Begin middle\n";
>
> system "$inner.pl";
>
> print "End middle\n";
>
> open my $MIDDLE_LOG, '>', 'middle.log';
> print $MIDDLE_LOG "middle, pid=$$\n";
> close $MIDDLE_LOG;
> ===== end middle.pl =====
>
> ===== inner.pl =====
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> print "In inner\n";
>
> open my $INNER_LOG, '>', 'inner.log';
> print $INNER_LOG "inner, pid=$$\n";
> close $INNER_LOG;
> ===== end inner.pl =====
>
> On Cygwin or Linux, log.txt contains:
> ==========
> outer calling middle
> Begin middle
> In inner
> End middle
> outer after middle
> ==========
>
> On Windows (executing outer.pl from a CMD window), log.txt contains:
> ==========
> outer calling middle
> Begin middle
> In inner
If this were true, you wouldn't have a problem. I suspect a cut and
paste error. 'In inner' should be missing.
> End middle
> outer after middle
> ==========
>
I'm running perl 5.8.8 and got the same behavior you did. I've had
trouble with letting DOS do the file association (running ./outer.pl vs.
perl outer.pl)
--
-brian
|