0

My code is:

  perl -e'
  use strict; use warnings;

  my $a={};

  eval{ test(); };

  sub test{
     print "11\n";
     if( $a->{aa} eq "aa"){
        print "aa\n";
     }
     else{
        print "bb\n";
     }
  }'

Output on Terminal is:

  11
  Use of uninitialized value in string eq at -e line 9.
  bb

If I redirect in file, the output order differ. Why?

  perl -e'
  ...
  ' > t.log 2>&1

cat t.log:

  Use of uninitialized value in string eq at -e line 9.
  11
  bb

My perl Version:

  This is perl 5, version 18, subversion 4 (v5.18.4) built for x86_64-linux-thread-multi
  (with 20 registered patches, see perl -V for more detail)
1
  • 3
    Output to STDERR is usually not buffered while other output is buffered. Add a $|++; after the use cases and all of your output will be unbuffered and the sequence will be what you expect. Commented Apr 13, 2015 at 8:26

2 Answers 2

4

A simpler demonstration of the problem:

$ perl -e'print("abc\n"); warn("def\n");'
abc
def

$ perl -e'print("abc\n"); warn("def\n");' 2>&1 | cat
def
abc

This is due to differences in how STDOUT and STDERR are buffered.

  • STDERR isn't buffered.
  • STDOUT flushes its buffer when a newline is encountered if STDOUT is connected to a terminal.
  • STDOUT flushes its buffer when it's full otherwise.

$| = 1; turns off buffering for STDOUT[1].

$ perl -e'$| = 1; print("abc\n"); warn("def\n");' 2>&1 | cat
abc
def

  1. Actually, the currently selected handle, which is the one print writes to if no handle is specified, which is STDOUT by default.
Sign up to request clarification or add additional context in comments.

Comments

0

It's only an autoflush problem NO eval question.

Solution is:

perl -e'
use strict; 
use warnings;

$|++; # <== this autoflush print output

my $a={};
test();

sub test{ 
   print "11\n";
   if( $a->{aa} eq "aa"){
      print "aa\n";
   }
   else{
      print "bb\n";
   }
}' > t.log 2>&1

In some cases on terminal is the same problem:

perl -e'print("abc"); print(STDERR "def\n"); print("ghi\n");'

The only save way to get correct order, is turn on autoflush!

@dgw + ikegami ==> thank's

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.