I’m trying to use stdbuf
to control buffering for a process in terminal — specifically, using stdbuf -o0
to prevent buffering when piping output onward, roughly as described in this answer — but it doesn’t seem to work as expected, or indeed have any effect. Compare the output of the following commands:
{ echo 'foo' ; sleep 2 ; echo 'boo'} | grep 'oo'
{ echo 'foo' ; sleep 2 ; echo 'boo'} | grep 'oo' | cat
{ echo 'foo' ; sleep 2 ; echo 'boo'} | stdbuf -o0 grep 'oo' | cat
{ echo 'foo' ; sleep 2 ; echo 'boo'} | stdbuf -o1M grep 'oo'
In the first, grep processes and outputs each line as it’s received. In the second, the output appears all together after 2 seconds — as explained here, grep buffers its output when not outputting to a terminal. Both of these are as expected. The third one is the surprise: according to the first linked answer and all other documentation/discussion I can find, stdbuf -o0
should prevent grep buffering its output, so that this ends up acting like the first command. However, on my Macs it acts like the second command — output arrives all together after 2 seconds. Similarly, the fourth command should (as I understand) cause grep to buffer its output, and so act like the second — but it doesn’t, it gives incremental output like the first.
Why is stdbuf
not having any effect here — do other Mac users get the same results? And is there an altnernative way to generally prevent buffering in pipes? I’ve tried stdbuf -oL
(line buffering), and this similarly doesn’t have any effect. I’ve also tried with gstdbuf
, i.e. the version installed by Homebrew’s coreutils
, and that also has no effect; both stdbuf
and gstdbuf
are version 9.5. I’ve tried this on three Macs, variously running Sonoma 14.4.1 and Ventura 13.6.6, and Monterey 12.7.4, with identical results. I’ve tried unbuffer
from the expect package; that doesn’t have any effect here either. And I’ve tried with other pipeline targets besides cat
; they all seem to show the same behaviour.
The grep-specific option --line-buffered
does work, as does replacing grep
by ag
, which doesn’t buffer for pipes by default. However, my actual use-case is with ripgrep-all (rga
) which buffers in pipelines like grep but doesn’t offer a line-buffering or non-buffering option, and this seems to be a general issue with stdbuf
and unbuffer
(I can’t find any test in which they seem to have any effect), so I’d really like to find a general answer if possible.
stdbuf
? I cannot find it in Monterey or Ventura.coreutils
rather than builtin (I already had them installed for other purposes).