help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: weird interaction between builtin cat and trap


From: Chet Ramey
Subject: Re: weird interaction between builtin cat and trap
Date: Thu, 14 Apr 2022 11:30:20 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Thunderbird/91.8.0

On 4/14/22 11:14 AM, Jesse Hathaway wrote:
On Thu, Apr 14, 2022 at 9:37 AM Peng Yu <pengyu.ut@gmail.com> wrote:
This code is the even simpler to reproduce the error.

$ cat ./main.sh
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

enable -f "$BASH_LOADABLES_PATH"/cat cat
trap 'echo EXIT' EXIT
seq 1000000 | builtin cat | {
         :
} {fd}<&0
$  ./main.sh
cat: write error: Broken pipe
EXIT

I think this is a difference in implementation, rather than a bug.
The builtin cat writes any errors to stdout and exits 1, whereas
cat from coreutils sets its exit code to 141 on receiving a
Broken Pipe(32), but does not write anything to stderr.

More or less. The trap has something to do with it, too.

The builtin cat catches and reports write errors before it checks for fatal
signals, including SIGPIPE. The coreutils cat just dies due to SIGPIPE
(exit status 141).

The trap EXIT causes bash to install a signal handler for the fatal
signals, including SIGPIPE. (All it does is clean up, run the exit trap,
and resend the signal to itself. And in this case the child running
cat doesn't run the exit trap, so it's just a passthrough.)

The coreutils cat doesn't do that. It may or may not check for write
errors, but it certainly doesn't catch SIGPIPE. It terminates before it
even has a chance to check for write errors.

--
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://tiswww.cwru.edu/~chet/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]