Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: subtle `echo' bug



On Jun 14, 10:12pm, Andrey Borzenkov wrote:
}
} This happens randomly

It's not a bug in echo, and the strange construct with the curly braces
has nothing to do with it.  Try this:

i=0
j=0
repeat 10 do
  i=0
  ((++j))
  seq 1 3 |while read n; do ((++i)); set | : $n; done
  print $i
done
print $i $j $n

Note that both loops exit, without ever executing "print $i", often
after only one pass.  (It's also important that you use a newline, not
a semicolon, after the final "done", or even the last "print" is not
executed.)

This affects any builtin that writes to its standard output, so the
problem is almost certainly resulting from a write error on stdout
because the builtin on the rightmost end of the pipeline is never
reading from its stdin.  When you use an external command on the far
right, a process is forked and the OS allocates some buffer space for
the pipe, and thus silently swallows the output; but when a builtin
is on the far right, that command is executed in the parent shell and
no such buffer is created.

You can see this in action by forcing external execution of the final
command by putting parens around it:

  seq 1 3 |while read n; do ((++i)); { : | set } | (: $n); done

I's sure you could also get the loop to fail with /bin/echo on the far
right by having the stuff inside { } emit a large enough volume to
overflow the OS pipe buffer.

In short, if you write nonsense code, you get nonsense results.  Don't
try to feed input to a command that doesn't want it.



Messages sorted by: Reverse Date, Date, Thread, Author