On 28/12/2020 14:21, Allan Odgaard wrote:
On 28 Dec 2020, at 11:32, Nicolai Dagestad wrote:
It might be something fishy with my machine, with:
python -c "print('0'*4097)" | tr 0 1 | head -c 10
I get the broken pipe on my laptop, but on none of my other machines
running arch...
Background:
In the above line `head` reads 10 bytes and then closes its stdin (which
is stdout for `tr`).
When a program writes to a closed pipe (stdout), it will receive SIGPIPE
which by default will terminate the process, so normally `tr` will be
terminated (silently) when nobody reads its output.
The reason for the 4096 bytes is due to buffering, `tr` can succesfully
fill up the buffer before triggering a SIGPIPE signal.
One can set SIGPIPE to be ignored, this will be inherited by a child
process during fork.
If SIGPIPE is being ignored, then it looks very much like `tr` *will*
output an error message, as then `fwrite` will fail and output an error
judging by this code:
https://github.com/coreutils/coreutils/blob/fb64712c4d79a542bae533034c6c4802eae555fd/src/tr.c#L1585-L1587
My theory: Someone has set SIGPIPE to be ignored, for the process that
spawns `pass` (and your test).
A small anecdote about this problem from 15 years ago: I had a problem
with the makewhatis cron job starting to emit mail to root about broken
pipes (thousands of lines). When I ran the job by hand, it all worked
fine. After a reboot, it also worked fine.
After quite a while of headscratching, the cause was found: When RPM
(actually up2date) ran, it ignored the SIGPIPE signal (in order to close
the rpmdb cleanly on write error). If the cron package was updated, the
cron daemon was restarted, with SIGPIPE still ignored. Cron did not
touch signal handlers during startup, so the result was that all cron
jobs launched thereafter would get this very confusing behaviour.
These days systemd makes sure services are starting in a clean and
consistent state, so this is less likely to crop up again :-)
--
Kjetil T. Homme
Redpill Linpro - Changing the Game