重定向到stdout的tcl exec结果也需要存储

时间:2012-09-27 10:19:14

标签: exec tcl stdout

湖看看这两行

案例1

set cvsUpdStr [exec cvs -qn upd]

案例2

set cvsUpdStr [exec cvs -qn upd >&@stdout]

对于第一种情况cvsUpdStr是命令的输出,但在命令执行期间没有打印出任何内容。对于第二种情况,屏幕上会打印cvs upd命令输出,但cvsUpdStr为空。如何组合它们以便打印出cvs upd的结果,并将相同的输出存储在cvsUpdStr变量中?

1 个答案:

答案 0 :(得分:4)

有两种可能性。将其作为管道(使用open |...创建)运行,并通过存储和打印消息来处理消息,或使用Unix tee实用程序。第二种选择肯定更简单!

# I like to spell out “update” in full
set cvsUpdStr [exec cvs -qn update | tee /dev/tty]

tee程序将其标准输入发送到其正常标准输出加上命名文件;我们使用/dev/tty将其发送到当前终端。

但请注意,由于缓冲输出,cvs的输出可能会延迟很长时间。这只是将库输出发送到非终端时C库的I / O处理的默认行为,如果您需要立即输出,则可能会出现问题。解决这个问题非常复杂(你最终会使用Expect)所以如果你对输出突发感到满意,那就别管它吧......


在Windows上,您需要以其他方式执行此操作。

set pipe [open |[list cvs -qn update] "r"]
while {[gets $pipe line] >= 0} {
    append cvsUpdStr "$line\n"   ;# Note the \n at the end!
    puts $line
}
close $pipe                      ;# Any errors turn up here!

具有|[list ...]的构造在Tcl术语中相当不寻常,但在这种情况下使用它是正确的。 (如果open的“文件名”的第一个字符是|,则参数的 rest 将被视为用于构建管道的参数列表。 )