How to write to stderr so people will like you
utcc.utoronto.ca
utcc.utoronto.ca
Standard Error is unbuffered: http://www.opengroup.org/onlinepubs/009695399/functions/stdi...
"When opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device."
$ ./unbuffer ./tst >/tmp/logit 2>&1; cat /tmp/logit
line 1
stderr line 1
line 2
stderr line 2
http://expect.nist.gov/example/unbufferSo, at least in C, I think flushing is intelligent enough not to block if no one's receiving the output.
grep foo *.txt|head -n10
Here head will close its stdin after having read 10 lines. If grep writes more it will get the EPIPE error on write (which may indirectly be called by fflush).This will also send the SIGPIPE signal which by default will kill the process, so grep is automatically terminated when no more output will be read from it.
You write a program called "thefirstprogram". Who cares what it does. However, a user is pushing its (standard) output into a second program called "asecondprogram". Now imagine "asecondprogram" has melted, but not terminated. It's basically in a screwed up state.
So the run command was:
bash-2.04> thefirstprogram | asecondprogram
I believe the flushing scheme advocated in the article is to be considered harmful, as you will in fact never see an error message if asecondprogram gets in a bad state and stops reading from stdin (and the buffers fill up).
I do agree the flushing makes for nicer ordering of error messages, but is more fragile.
Only used flushed output when you really need flushed output otherwise you'll get less resilience in the case of meltdown of cooperating programs.
If the second program is messed up, it makes no difference if you flush or not. You'll still never see an error message.
Stdin will fill up, flush or not, the program will block, and then sit there - no error message.
You could maybe detect if stdin is blocked and say something on stderr - but if you want to do that it makes no difference whatsoever if you flush stdout or not.
You have to explicitly pipe stderr as well if you don't want this behavior
Obviously you could make some complicated buffering scheme - but you can do that and flush things anyway. The flush or no flush makes no difference.
You're picking nits frankly. The system can be useful. But it does deadlock and/or cause delays if your output program stops reading from the pipe temporarily or permanently. The deadlocked secondprogram was just a simple example of when this happens.
This sort of behavior is a rare case. It is far from rare though in a less degenerate form. In the very simple case of displaying text on the command line you will fill your output buffer all the time, but with the flushes, you'll vastly slow the program down to the speed of text display in your terminal as you make all text output every time, as opposed to just when the buffer display program runs.
Which do you think will run faster: Cat without those flushes or cat with those flushes?
This technique is not universally applicable, as the article says. It does not fit all cases. It has costs.
It does also have applications. But it's not the suggested universal technique.
And the difference between "stop processing" and letting the IO block is what?
If you use blocking IO, you just silently fail.
I believe pipes are block-buffered and basically look just like redirecting to a file.
Anyway, if you want to see freakin' echo block because of this, try:
$ mkfifo foo
$ echo "OH HAI" > foo
<blocks>
In another xterm: $ cat foo
<echo unblocks and exits>.So yes, you are wrong here.
Could someone explain exactly why this is?
(Note that only stdout is the issue, see ready's comment.)
If you did a setbuf(stderr,NULL) as well as setbuf(stdout,NULL), you'd achieve the same effect that the author's going for, with no need to remember to flush.