Re: Windows [open |command] catching stderr?
- From: "Alexandre Ferrieux" <alexandre.ferrieux@xxxxxxxxx>
- Date: 21 Dec 2006 13:56:30 -0800
Darren New wrote:
Is there any way to catch the stderr from a command in Windows when
opening a command via [open] with a pipe?
Essentially, in UNIX I have
set x [open "|./ojexec </dev/null 2>@1" r]
Then I can log both stderr and stdout.
In Windows, it looks like I need to do
set x [open "|cmd.exe /c xyz.bat <nul:" r]
and then inside xyz.bat, I need to put
tclsh xyz.tsh 2>&1
in the bat file in order to get back the stderr.
A side note: why don't you just
set x [open "|cmd.exe /c {tclsh xyz.tsh 2>&1} <nul:" r]
?
If I use "|cmd.exe /c xyz.bat <nul: 2>@stdout" then the stderr goes to
stdout, but not to the pipe I'm listening on. (I.e., stderr output
doesn't trigger readable fileevents on $x)
Yes, and this is the right semantics. stdout is your interpreter's
current standard output, not the child's one (which is the write side
of an anonymous pipe). The fact that this has worked like 2>@1 for the
best part of Tcl's history is an accident :-) (I forget the date of
that fix)
Is there any way I can catch the stderr in Windows and also know when
the caller exits, without requiring the user to remember to put the
redirect in the .bat file?
Unless the child explicitly closes its stdout early in its life, you
can still count on an EOF to detect its death, even if it never writes
on its stdout. So the fileevent will notify you.
If you want its stderr and stdout to be merged, the idiom above (which
is only a minor variant of yours with no extra BAT file) should help.
But you may also want stdout and stderr to be separate; in this case
you need an outside standalone pipe:
set ch [open "|some_command 2>@ $pi1" r]
fileevent $ch readable callback1
fileevent $pi2 readable callback2
I know of two methods to create $pi1,2:
- a named fifo, created my mknod (*)
- an outside cat(*) created by
set pi2 [open "|cat" r+];set pi1 $pi2
(*): these commands are not available in vanilla Windows, but you can
get them in convergent environments like U/Win
Of course, the best would be a Tcl primitive to create standalone
anonymous pipes:
foreach {pi1 pi2} [pipe] break
I vaguely remember a discussion like this years ago, and that TclX did
provide it, at least in unix. I don't know for today and current
Windows.
If such a [pipe] finds supporters, I'll be happy to TIP...
-Alex
.
- References:
- Windows [open |command] catching stderr?
- From: Darren New
- Windows [open |command] catching stderr?
- Prev by Date: Problem with tests, after compiling Tix to install
- Next by Date: Re: Windows [open |command] catching stderr?
- Previous by thread: Windows [open |command] catching stderr?
- Next by thread: Re: Windows [open |command] catching stderr?
- Index(es):
Relevant Pages
|