On Sun, Sep 09, 2007 at 04:58:23PM +0200, Pierre-Philippe Coupard wrote:
[...]
>        while [ 1 ];do
>          echo Test1
>          echo Test2 >> file.txt
>          sleep 1
>        done
>
>        As expected, when this script is run in the background (&), the 
> console
>        slowly fills with "Test1" lines, and the file.txt file slowly fills 
> with
>        "Test2" lines.
>
>        Now exit the shell leaving the script running (don't simply close 
> the
>        xterm, that'd kill the script. Type "exit"). Since the terminal has
>        closed, stdout is closed, so "echo Test1" should fail. It doesn't,
>        instead it writes "Test1" lines into whatever open file descriptor 
> it
>        can find. In this case, file.txt starts filling up with
>
>        Test2
>        Test1
>        Test2
>        Test1
[...]

Bonjour Pierre-Philippe,

can be reproduced with 3.2.25 and with:

bash -c 'trap "" PIPE; sleep 1; echo a; echo b > a' | :

It seems to be down to the usage of stdio.

According to ltrace, echo seems to be doing printf("Test1\n")
followed by fflush(stdout). When the write(2) underneath
fflush() fails, "Test1\n" remains in the stdio buffer.

Then bash does an dup2(open("file.txt"), fileno(stdout)) instead
of doing an stdio freopen(3), so the next fflush(3) flushes both
"Test1\n" and "Test2\n" to the now working stdout.

Maybe bash can't use freopen(3) as that would mean closing the
original fd. Best is probably not to use stdio at all.

Note that zsh has the same problem, and AT&T ksh seems to have
an even worse problem (in the example above, it outputs "b\n"
twice). ash and pdksh are OK.

Best regards,
Stéphane


Reply via email to