I wrote a program (in Ruby) and it worked well. It prints out a few lines of text and then pause for a minute and then repeats the above.
It works well (in Mac OS X's terminal), but I noted that if I wanted to keep a record of the output, by using
ruby myscript.rb | tee record.txt
then the output won't be shown on the screen, until the output reaches a certain amount, perhaps a few kb. However, this could mean 5 or 10 minutes with nothing on the screen (and nothing in the file either if I press CTRL-C).
I could modify the program to flush the output, but I thought an app should be agnostic as to what is being used with the output to STDOUT. So can tee
be made to work well (perhaps with an option), or any other command could be used, or maybe it is an option of Bash or the Terminal app? Is there a way?
Best Answer
You thought wrongly. The runtime libraries of several programming languages, including the C and C++ languages, all share the semantics of changing the buffering according to whether they detect that the stream is attached to a terminal device.
This is a defined part of the language in many cases. The C language standard says, for example:
The usual choice if a stream is not attached to a terminal device is to select unit buffering, line buffering, or full buffering. Unit buffering and line buffering are usual for standard error; full buffering for standard output. But this does vary by language.
So to get the output to be not fully buffered when the output stream is a pipe in such lanugages you have to
stdbuf
command if your programming language is C or uses (the I/O streams part of) the C runtime library as its base (which some programming languages do not); orptybandage
that make the program think that its standard output is a terminal, whilst taking that output and sending it to the write end of the pipe.Further reading