This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: stdout/stderr handling by cygrunsrv/bash/tcl
- From: AJ Reins <tbisp at yahoo dot com>
- To: cygwin at cygwin dot com
- Date: Wed, 3 Mar 2004 16:33:39 -0800 (PST)
- Subject: Re: stdout/stderr handling by cygrunsrv/bash/tcl
--- Igor Pechtchanski <pechtcha@cs.nyu.edu> wrote:
> On Wed, 3 Mar 2004, Patrick Samson wrote:
>
> > --- Igor Pechtchanski wrote:
> > > On Tue, 2 Mar 2004, Patrick Samson wrote:
> > >
> > > > I run a service installed as:
> > > >
> > > > cygrunsrv --install pgr-daemon
> > > > --path /usr/bin/bash.exe
> > > > --args "--login /opt/pgreplica/bin/pgrd host1 host2"
> > > > --user pgreplicator
> > > > --shutdown
> > > >
> > > > Everything is fine with stdout. Messages are in /var/log/pgr-daemon.log
> > > >
> > > > But if my application, which is a TCL script, writes something on stderr
> > > > (as "puts stderr $msg"),
> > > > This message is written:
> > > > - at the beginning of the file, overwriting the existing stdout text.
> > > > - only when the service is stopped.
> > > >
> > > > Is it an as-is behaviour, a lack or a mistake in the command syntaxes,
> > > > or something wrong in cygrunsrv or bash or tcl?
> > >
> > > Patrick,
> > >
> > > WFM. I can't reproduce your problem on Win2k
> > > (without Tcl and --user).
> > > Here's what I did:
> > >
> > > $ mkdir /tmp/servicetest && cd /tmp/servicetest
> > > $ cat > service.sh
> > > #!/bin/bash
> > > terminate() {
> > > echo "Terminating" >&2
> > > exit 0
> > > }
> > > trap terminate INT
> > > echo "Starting service" >&2
> > > trap -p
> > > while true; do
> > > sleep 10
> > > echo "STDERR" >&2
> > > echo "STDOUT" >&1
> > > done
> > > $ cygrunsrv --install test-daemon --path /usr/bin/bash.exe --args "--login
> /tmp/servicetest/service.sh" --termsig INT --shutdown
> > > $ cygrunsrv -S test-daemon; sleep 30; cygrunsrv -E test-daemon
> > > $ cat /var/log/test-daemon.log
> > > Starting service
> > > trap -- 'terminate' SIGINT
> > > STDERR
> > > STDOUT
> > > STDERR
> > > STDOUT
> > > STDERR
> > > STDOUT
> > > Terminating
> > > $
> > >
> > > So, messages going to stdout/stderr were properly redirected. If the
> > > above works for you, try adding a Tcl call to the test script, and see
> > > if it changes anything.
> >
> > Your demo works as expected. But TCL introduces
> > the mess.
> >
> > I changed the script to:
> >
> > $ cat service.sh
> > #!/bin/bash
> > # the next line restart using tclsh \
> > exec tclsh "$0" "$@"
> >
> > puts "Starting service"
> > while {true} {
> > # wait 1 sec
> > after 1000
> > puts stderr "STDERR"
> > puts "STDOUT"
> > }
> > $ cygrunsrv -S test-daemon; sleep 3; cygrunsrv -E
> > test-daemon
> > $ cat /var/log/test-daemon.log
> > STDERR
> > STDERR
> > STDERR
> > STDERR
> >
> > STDOUT
> > STDOUT
> >
> > It looks like the overwriting of these two lines
> > (cr lf are replaced by space):
> > STDERR STDERR STDERR STDERR
> > Starting service STDOUT STDOUT STDOUT STDOUT
> >
> > Just for the understanding, another trial with the
> > script beginning with a write to stderr:
> >
> > $ cat service.sh
> > #!/bin/bash
> > # the next line restart using tclsh \
> > exec tclsh "$0" "$@"
> >
> > puts stderr "Write stderr"
> > puts "Starting service"
> > while {true} {
> > # wait 1 sec
> > after 1000
> > puts stderr "STDERR"
> > puts "STDOUT"
> > }
> > $ cygrunsrv -S test-daemon; sleep 3; cygrunsrv -E
> > test-daemon
> > $ cat /var/log/test-daemon.log
> > Starting serviSTDESTDOSTDESTDOSTDESTDOSTDESTDOUT
> >
> > Again the overwriting of these two lines:
> > Write stderr STDERR STDERR STDERR STDERR
> > Starting service STDOUT STDOUT STDOUT STDOUT
> >
> > If I run the TCL directly, it's ok, no surprise:
> > $ ./service.sh
> > Write stderr
> > Starting service
> > STDERR
> > STDOUT
> > STDERR
> > STDOUT
> > STDERR
> > STDOUT
> > <manually interruped with ctrl/c>
> > $ ./service.sh >service.log 2>&1
> > <manually interruped with ctrl/c>
> > $ cat service.log
> > Write stderr
> > Starting service
> > STDERR
> > STDOUT
> > STDERR
> > STDOUT
> > STDERR
> > STDOUT
> >
> > I wouldn't use this syntax, but it shows the same
> > problem, so it may be a clue:
> >
> > $ ./service.sh >service.log 2>service.log
> > <manually interruped with ctrl/c>
> > $ cat service.log
> > Starting serviSTDESTDOSTDESTDOSTDESTDOUT
> >
> > Continuing on this way, consider:
> > serviceSH.sh as the shell script of Igor,
> > serviceTCL.sh as the TCL script.
> >
> > $ ./serviceSH.sh >service.log 2>service.log
> > trap -- 'terminateSTDERR
> > STDERR
> > Terminating
> >
> > $ ./serviceSH.sh >>service.log 2>>service.log
> >
> > Starting service
> > trap -- 'terminate' SIGINT
> > STDERR
> > STDOUT
> > STDERR
> > STDOUT
> > STDERR
> > STDOUT
> > Terminating
> >
> > $ ./serviceTCL.sh >service.log 2>service.log
> >
> > Starting serviSTDESTDOSTDESTDOSTDESTDOUT
> >
> > $ ./serviceTCL.sh >>service.log 2>>service.log
> >
> > Starting serviSTDESTDOSTDESTDOSTDESTDOSTDESTDOUT
> >
> > Can someone tell us how cygrunsrv manages the
> > redirections? It's a step toward the explanation.
>
> cygrunsrv redirects each file separately (like the '>>a 2>>a' syntax).
> This is obviously a Tcl problem. It seems that Tcl attempts to manage its
> own buffering on STDOUT/STDERR, even when they are redirected.
>
> Try adding an 'exec 2>&1' just before the 'exec tclsh "$0" "$@"' in your
> serviceTCL.sh script. Hopefully, Tcl will inherit the stderr from the
> parent process... If this works, you can add it to your main script,
> since you know that both stdout and stderr will eventually go to the same
> file anyway.
> Igor
Doesn't Tcl buffer stdout by default? (Yes, that is a rhetorical question)
You could also do:
fconfigure stdout -buffering none
to make stdout the same as stderr (not buffered by default).
__________________________________
Do you Yahoo!?
Yahoo! Search - Find what you?re looking for faster
http://search.yahoo.com
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/