unbuffer
unbuffer is a small utility from the Expect distribution that disables the output buffering programs apply when their stdout is redirected into a pipe. See the unbuffer(1) man page.
The problem
C stdio chooses a buffering strategy based on where stdout points: line-buffered when attached to a terminal (flush on every newline), but fully buffered (4–8 KB blocks) when attached to a pipe or file. The result is the classic annoyance of piping a long-running command through tee to watch progress and save a log — and seeing nothing for minutes at a time because the output is sitting in the child’s buffer. 1
Usage
unbuffer $APPLICATION | tee $LOGunbuffer runs the command attached to a pseudo-terminal, so the child believes it is interactive and flushes per line; the pty’s output is then forwarded down the pipe in real time. 2
Alternatives
stdbuf -oL $APP— injectsLD_PRELOADto force line buffering in the child; lighter than a pty but only affects programs using C stdio (not, e.g., some statically linked Go binaries). See ld-preload-trick for the underlying mechanism.- Application flags — some tools have their own switch:
grep --line-buffered,python -u(unbuffered; see python),tcpdump -l. script -c "$APP" /dev/null | tee $LOG— same pty trick via util-linuxscript(1), no Expect dependency.
Caveat: because unbuffer allocates a pty, the child may also enable other interactive behaviors (color output, progress bars, pagers). That is usually what you want for live logs, but it can pollute machine-read output.