How to redirect output from an infinite-loop program

I have a program running an infinite loop and will not terminate until receiving a CTRL+C signal. What I want to do is redirecting the output from this program into a file, say log for example. However, after I CTRL+Ced the program, nothing is recorded into log. I think it maybe some problem related to I/O buffer, but have no idea how to solve it. Am I on the right track? How to dump output from an infinite-loop program into a file?


Solution 1:

If your program is using the standard output functions (e.g. puts, printf and friends from stdio.h in C, cout << … in C++, print in many high-level languages), then its output is buffered: characters accumulate in a memory zone which is called a buffer; when there's too much data in the buffer, the contents of the buffer is printed (it's “flushed”) and the buffer becomes empty (ready to be filled again). If your program doesn't produce much output, it may not have filled its buffer yet.

When you kill your program with Ctrl+C, unless you've set a signal handler for SIGINT, it just dies. The contents of any unflushed buffer is lost.

You have three possibilities:

  • Write a signal handler for SIGINT that flushes the output buffer (fflush(stdout), or fflush(NULL) to flush all buffers).
  • Set your program to not buffer its output: call setvbuf(stdout, NULL, _IONBF, 0). (See C equivalent of autoflush (flush stdout after each write)?)
  • Run your program under an environment that pretends to be a terminal, so that no buffering happens. See Turn off buffering in pipe

Solution 2:

A script (with an infinite loop or not) should save the redirected data gradually, so the nature of the script should bear no result on the outcome. Data should be written in gradually ...

Or (if there is no output at all, even without redirect) you might wanna try fflush(stdout) or something to that effect.

Just a thought (though highly unlikely) ... are you sure redirecting STDOUT is what you ought to do? Isn't it by any chance STDERR? Try running the binary/script/... with:

$ ./program 2> ./stderr_out

and then cat ./stderr_out to make sure STDERRis not the one...