To be clear with the title question, I understand why the former dies. I don't understand why the latter doesn't, just for adding a | cat
to the loop body.
Also maybe related,
while true; do echo y; done
dies immediately when I do ^C
, but killing
while true; do echo y | cat; done
often takes hitting ^C
more than once. Sometimes once works, other times 2 or 3 times works, then there are times where I need to hold ^C
for a while for it to die.
Both behaviors happen in both bash and zsh, although the ^C
one seems to be rarer with bash.
For both behaviors, this isn't limited to adding the pipe to cat
. | dd
, | tee
, etc. also cause them. Even echo y | true
causes it. It seems to be the presence of any pipe in the loop body.
Why does the presence of a pipe in a loop body change the loop's response to signals?
^C
works, I guess^C
stopping the loop depends on whether an external program is currently running or not. In my example with the pipe, it only works if it's delivered in between iterations. The one without the pipe doesn't have external invocations, so it always works. It also explains why more conventional loops with external programs that last longer and have in-between shell code almost always take exactly 2^C
in quick succession to kill the loop. – JoL Apr 15 '20 at 19:32