Output is coming in the wrong order

Here's a typical program that exhibits this common problem:

  print "FILE LISTING OF DIRECTORY $dir:\n";
  print "---------------------------------\n";
  system("ls -l $dir");
  print "---------------------------------\n";
Run this on a terminal, and it comes out OK. But if you run it with STDOUT redirected to a file, it doesn't work: the header appears after the file listing, instead of at the top.

So why didn't it work? Standard output is buffered, so the header lines are saved in the buffer and don't get to the file just yet. Then you run ls, which has its own buffer, and ls's buffer is flushed when ls exits, so ls's output goes into the file. Then you print the footer line and it goes into your programs buffer. Finally, your program finishes and flushes its buffer, and all three lines go into the output file, after the output from ls. To fix this, make STDOUT hot.

Now that we know why the data got into the file in the wrong order, that raises another question: If we have it print to the terminal, why does the output come out in the right order instead of the wrong order? Because when STDOUT is attached to the terminal, it is in line buffered mode, and is flushed automatically whenever we print a newline character to it. The two header lines are flushed immediately, because they end with newlines; then comes the output of ls, and finally the footer line.

Try again, now setting a non-buffered mode for STDOUT:

  $|=1;
  print "FILE LISTING OF DIRECTORY $dir:\n";
  print "---------------------------------\n";
  system("ls -l $dir");
  print "---------------------------------\n";
Table of Contents.
Previous.