OS: Windows with Cygwin
If stdout and stderr are redirected to the same
file, they overwrite each other.
Test case:
Consider the script:
$ cat service.sh
#!/bin/bash
# the next line restart using tclsh \
exec tclsh "$9" "$@"
puts stderr "Write stderr"
puts "Starting service"
while {true} {
# wait 1 sec
after 1000
puts stderr "STDERR"
puts "STDOUT"
}
I use a Windows service manager which
does internally something like:
$ ./service.sh >>service.log 2>>service.log
So it gives:
Starting serviSTDESTDOSTDESTDOSTDESTDOUT
It looks like the overwriting of these two lines:
(cr lf are replaced by space):
Write stderr STDERR STDERR STDERR
Starting service STDOUT STDOUT STDOUT
In comparison, a pure shell script like:
$ cat serviceSH.sh
#!/bin/bash
echo "Starting service" >&2
while true; do
sleep 10
echo "STDERR" >&2
echo "STDOUT" >&1
done
run as:
$ ./serviceSH.sh >>service.log 2>>service.log
Gives an expected result:
Starting service
STDERR
STDOUT
STDERR
STDOUT
STDERR
STDOUT
Note:
adding: fconfigure stdout -buffering none
didn't change anything.
Logged In: YES
user_id=79902
Stuff like this is why O_APPEND isn't the same as seeking to
the end yourself. (Told you so, but can't remember the
tracker item ID when I did it.)
Logged In: YES
user_id=75003
Jun 28, 2005 dkf fixed this for unix, adding the O_APPEND
flag to the appropriate places in the pipeline mgmt. He also
noted that this is unfixable for Windows. However as Cygwin
is involved, i.e. a unix emuklation layer, his change may
have fixed the described situation.
Given the date above this might just have slipped into
8.4.11. If not, then the CVS head of the 8.4 branch has to
be used for checking this.
Logged In: YES
user_id=1312539
This Tracker item was closed automatically by the system. It was
previously set to a Pending status, and the original submitter
did not respond within 14 days (the time period specified by
the administrator of this Tracker).
Logged In: YES
user_id=79902
Note that if the channel does not have an
O_APPEND-equivalent tag on it at the OS level (whatever that
means!) there is no way to get rid of the race condition
because seek+read isn't an atomic operation.
Not that this would matter except basic Windows file handles
don't have such a flag (I don't know cygwin enough to
comment on whether they've managed to add it.) You might be
able to achieve something by adding locking to the mix, but
that's horrific. If anyone wants to fix this for cygwin
(it's not fixable for straight win32) they should start by
writing a patch that allows them to pass a test like
exec-19.1...