Redirecting STDOUT under ActivePerl on Windows XP

Discussion in 'Perl Misc' started by Keith Thompson, Jun 26, 2008.

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

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 26, 2008
    #1
    1. Advertising

  2. 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 "${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)

    --
    -brian
    Brian Helterlilne, Jun 27, 2008
    #2
    1. Advertising

  3. Brian Helterlilne <> writes:
    > 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";

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

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 27, 2008
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Douard
    Replies:
    4
    Views:
    804
    David Bolen
    Feb 3, 2005
  2. Elad
    Replies:
    0
    Views:
    401
  3. Ian Hobson
    Replies:
    0
    Views:
    634
    Ian Hobson
    Sep 6, 2010
  4. Ian
    Replies:
    0
    Views:
    388
  5. Ted
    Replies:
    7
    Views:
    540
    Sisyphus
    Dec 16, 2006
Loading...

Share This Page