[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bash incorrectly handles 'echo' + SIGPIPE under some situations on L
From: |
Chris Siebenmann |
Subject: |
Re: bash incorrectly handles 'echo' + SIGPIPE under some situations on Linux |
Date: |
Wed, 06 Jan 2016 11:43:17 -0500 |
> > If Bash writes to stdout with the built in echo and gets a SIGPIPE,
> > it can incorrectly buffer and then repeat this would-have-been output
> > in at least $(...) things invoked in a cleanup function and in fact
> > in some other contexts as well. To see this in action, create the
> > following script as /tmp/repro:
> >
> > #!/bin/bash
> > function cleanup() {
> > r1=$(/bin/echo one)
> > r2=$(/bin/echo two)
> > echo $r1 '!' $r2 1>&2
> > #echo $r1 '!' $r2 >>/tmp/logout
> > }
> > trap cleanup EXIT
> > sleep 1
> > echo final
> >
> > Run it as '/tmp/repro | false'. The output produced is the clearly
> > incorrect:
> > $ /tmp/repro | false
> > final
> > one final ! two final
>
> Thanks for the report. This appears to be easily reproducible on Linux.
>
> Adding a call to fpurge() to discard buffered output on stdout before
> dup2() replaces file descriptor 1 in the child process fixes it.
Note that the problem isn't only in the children; the parent process
itself has a problem too, as the 'final' by itself should not be printed
either (and comes entirely from the parent).
$ cat repro2
#!/bin/bash
function cleanup() {
echo end 1>&2
}
trap cleanup EXIT
sleep 1
echo final
$ ./repro2 | false
final
end
Strace on Linux confirms that this only fork()s to do the sleep; the
entire sequence from returning from sleep through the end happens in the
main Bash process.
- cks