X.M*_*.M. 4 stdout tcl exec stderr
我发现tcl exec命令首先从stdout返回字符串然后是stderr.例如,我的以下"测试脚本"按此顺序生成消息:
puts "test started"
puts stderr "some non-fatal error goes to stderr"
puts "test passed"
Run Code Online (Sandbox Code Playgroud)
然后我像这样执行脚本:
set ret [ catch { exec sh -c $cmd } msg ]
Run Code Online (Sandbox Code Playgroud)
而我从$ msg得到的是:
test started
test passed
some non-fatal error goes to stderr
Run Code Online (Sandbox Code Playgroud)
这真的让我很难得到正确的结果.
有人可以知道是否可以按顺序从stdout和stderr获取消息,并且:
1)请不要像这样重定向,这样可以确保它们全部按顺序排列:
set ret [ catch {exec $cmd >&log.txt} msg ]
Run Code Online (Sandbox Code Playgroud)
2)我必须在我的 tcl脚本中调用那个 tcl脚本,抱歉
3)我也不能直接获取.tcl测试脚本,因为在两者之间调用了其他脚本,如果我的tcl脚本只是源于那个 tcl脚本它就不会工作.
我使用的是tclsh 8.3
不确定这是否要求太多.我希望有人可以解决这个问题.谢谢.
首先,让我们为测试目的定义一个简单的命令,我们可以肯定会测试我们需要的东西:
set cmd "echo a; echo b >&2; echo c"
Run Code Online (Sandbox Code Playgroud)
接下来,我们使用一些额外的帮助来处理stdout和stderr流的合并(为了清楚起见,将命令分成几行,以便我们可以看到catch包装器的位置和包装的exec位置):
set ret [catch {
exec sh -c $cmd |& cat
} msg]
Run Code Online (Sandbox Code Playgroud)
如果我们测试一下,我们会发现我们$ret已经存在0,并且$msg正确地排序:
a
b
c
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?诀窍是|&,在管道到另一个进程时进行合并.(我们之所以使用cat它是因为它只是通过而不会干扰.)
如果您使用的Tcl 8.6(测试版),您可以使用chan pipe来产生可以重定向通道stdout,并stderr与2>@ fileId形式,但不是那么对你有用.(你知道8.3已经过时了吗?甚至8.4不再真正支持; 8.5是推荐的生产级代码.)
| 归档时间: |
|
| 查看次数: |
2772 次 |
| 最近记录: |