Redirecting STDOUT under ActivePerl on Windows XP

K

Keith Thompson

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 = '.\\';
}
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 "${prefix}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 = '.\\';
}
else {
$prefix = './';
}
print "Begin middle\n";

system "${prefix}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
End middle
outer after middle
==========
 
B

Brian Helterlilne

Keith said:
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 "${prefix}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 "${prefix}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)
 
K

Keith Thompson

Brian Helterlilne said:
Keith said:
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"; [...]
if ($^O =~ /^mswin/i) {
$prefix = '.\\';

$prefix = 'perl .\\';
}
else {
$prefix = './';
}
[...]
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
==========

Right on both counts. The "In inner" is missing, and yes, it was a
copy-and-paste error.
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)

Running .\outer.pl works for me, but yes, "perl outer.pl" should work
as well.
 

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,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top