20

Is there a difference between unbuffer(1) and stdbuf(1)? From what I gather, unbuffer makes more than the "best effort" of calling the libc function set(X)buf at the beginning, and then letting things be?

2 Answers 2

24

They work in completely different ways.

The program unbuffer uses expect to run the named command. Because expect creates a pseudo-tty to attach to the stdout of the child process, the child might be fooled into thinking that it should use line-buffering instead of block-buffering. Some programs will change their behavior when isatty(stdout) is true, others won't, and it is very hard to know which will and which won't.

The program stdbuf attempts to put libstdbuf in front of libc for dynamically loaded binaries. Where libstdbuf redefines the default buffering strategy of the libc stdio calls.

I found this out by

apt-get source expect coreutils

and reading the relevant source for each program.

2
  • Some worrying stuff (from manpage): unbuffer -p may appear to work incorrectly if a process feeding input to unbuffer exits. Consider: process1 | unbuffer -p process2 | process3 If process1 exits, process2 may not yet have finished. It is impossible for unbuffer to know long to wait
    – dan3
    Commented Oct 23, 2013 at 22:05
  • 1
    It seems stdbuf can also control the stdin buffering of programs that use C streams, which seems important. Perhaps this should be included in the answer for the benefit of future readers.
    – dan3
    Commented Oct 25, 2013 at 8:47
2

TL;DR

The older, accepted answer is still correct. The main difference in my own experience is that unbuffer is simpler to use and provides only one switch (-p) for use in pipelines to buffer standard input, which stdbuf will not do.

While specific use cases may vary, I'd offer the follow general advice:

  1. Use unbuffered if you need to buffer standard input and understand the limitations of buffering standard input, i.e. hanging if the pipeline exits early or early termination on EOF.
  2. Use stdbuf when you need separate control over the buffering for input, output, and error I/O streams, and if you don't need to buffer standard input.

Stdbuf from Coreutils

The stdbuf utility, which is part of GNU , offers separate flags for input, output, and error streams. Notably, the man page makes the following key points:

  1. Commands like tee that adjust buffers themselves will be unaffected.
  2. Filters that don't use I/O streams aren't affected.
  3. Line buffering is invalid with standard input.

So, in general, stdbuf gives you more control than unbuffer, but there are a number of caveats. man 1 stdbuf (or man 1 gstdbuf on some systems) says:

NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does for example) then that will override corresponding changes by 'stdbuf'. Also some filters (like 'dd' and 'cat' etc.) don't use streams for I/O, and are thus unaffected by 'stdbuf' settings...

BUGS
On GLIBC platforms, specifying a buffer size, i.e., using fully buffered mode will result in undefined operation.

Unbuffered from Expect

The unbuffered command, which is one of the standard command line example tools, offers fewer knobs to twiddle. This may or may not be a benefit for you. Personally, I prefer simplicity unless I need the additional knobs. On the other hand, while stdbuf won't work with standard input, unbuffered can when using the -p option.

Normally, unbuffer does not read from stdin. This simplifies use of unbuffer in some situations. To use unbuffer in a pipeline, use the -p flag.

However, this behavior comes with a caveat and some further explanation about why if you read man 1 unbuffered:

unbuffer -p may appear to work incorrectly if a process feeding input to unbuffer exits. Consider:

             process1 | unbuffer -p process2 | process3

If process1 exits, process2 may not yet have finished. It is impossible for unbuffer to know long to wait for process2 and process2 may not ever finish, for example, if it is a filter. For expediency, unbuffer simply exits when it encounters an EOF from either its input or process2.

In such cases, unbuffered recommends hand-tuning the pipeline, using Expect directly, or various other workarounds instead.

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .