开发者

tcl exec reads stdout first then stderr?

开发者 https://www.devze.com 2023-01-12 11:55 出处:网络
I found tcl exec command returns string from stdout first then stderr. For example, my following \"test script\" generates messages in this order:

I found tcl exec command returns string from stdout first then stderr. For example, my following "test script" generates messages in this order:

puts "test started"
puts stderr "some non-fatal error goes to stderr"
puts "test passed"

Then I execute the script like this:

set ret [ catch { exec sh -c $cmd } msg ]

and what I get from $msg is:

test started
test passed
some non-fatal error goes to stderr

and this is really making me hard to get the correct result.

Can someone let if know if it is possible to get the messages from both stdout and std开发者_StackOverflowerr in order, and:

1) please do not redirecting like this, which can get them all in order indeed:

set ret [ catch {exec $cmd >&log.txt} msg ]

2) I have to call that tcl script in my tcl script, sorry

3) Nor can I source the .tcl test script directly because there are other scripts called between the two and it wont work if my tcl script just source that tcl script.

I am using tclsh 8.3

Not sure if this is asking too much. I hope someone may figure this out. Thanks.


First off, let's define a simple command for the purposes of testing that we can be sure will test just what we need:

set cmd "echo a; echo b >&2; echo c"

Next, we use a little extra helper to handle the merging of the stdout and stderr streams (splitting the command over several lines for clarity only so that we can see where the catch wrapper is and where the wrapped exec is):

set ret [catch {
   exec sh -c $cmd |& cat
} msg]

If we test that, we'll find that we get $ret being 0, and $msg being the correctly ordered:

a
b
c

How does it work? The trick is |&, which does the merge when piping to another process. (We use cat because it just passes things through without interfering.)

If you're using Tcl 8.6 (in beta) you can use chan pipe to produce a channel that you can redirect stdout and stderr into with the 2>@ fileId form, but that's not so useful to you. (You are aware that 8.3 is rather obsolete? Even 8.4 is no longer really supported; 8.5 is what production-grade code is recommended to target.)

0

精彩评论

暂无评论...
验证码 换一张
取 消