Turn off buffering in pipe
Another way to skin this cat is to use the stdbuf
program, which is part of the GNU Coreutils (FreeBSD also has its own one).
stdbuf -i0 -o0 -e0 command
This turns off buffering completely for input, output and error. For some applications, line buffering may be more suitable for performance reasons:
stdbuf -oL -eL command
Note that it only works for stdio
buffering (printf()
, fputs()
...) for dynamically linked applications, and only if that application doesn't otherwise adjust the buffering of its standard streams by itself, though that should cover most applications.
You can use the unbuffer
command (which comes as part of the expect
package), e.g.
unbuffer long_running_command | print_progress
unbuffer
connects to long_running_command
via a pseudoterminal (pty), which makes the system treat it as an interactive process, therefore not using the 4-kiB buffering in the pipeline that is the likely cause of the delay.
For longer pipelines, you may have to unbuffer each command (except the final one), e.g.
unbuffer x | unbuffer -p y | z
Yet another way to turn on line-buffering output mode for the long_running_command
is to use the script
command that runs your long_running_command
in a pseudo terminal (pty).
script -q /dev/null long_running_command | print_progress # (FreeBSD, Mac OS X)
script -q -c "long_running_command" /dev/null | print_progress # (Linux)