tcl exec result redirected to stdout need to be stored too

Lake a look at this two lines

case 1

set cvsUpdStr [exec cvs -qn upd]

case 2

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

For the first case cvsUpdStr is the output of the command, but there is nothing printed out during command execution. For the second case the cvs upd command output is printed on the screen, but cvsUpdStr is empty. How to combine them so that it will print out the result of cvs upd and also will store the same output in cvsUpdStr variable?


There are two possibilities. Either run it as a pipeline (created with open |... ) and handle the messages as they come in by storing them and printing them, or use the Unix tee utility. The second alternative is definitely simpler!

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

The tee program sends its standard input to its normal standard output plus the named file; we use /dev/tty to send it to the current terminal.

Note however that you may get long delays in the output of cvs due to it buffering its output. This is just the default behavior of the C library's I/O handling when sending output to a non-terminal, and can be a problem if you need the output instantly. Fixing this gets quite involved (you end up using Expect) so if you're happy with the output being bursty, just leave it alone…


On Windows, you need to do it the other way.

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

The construct with |[list ...] is rather unusual in Tcl terms, but it is the correct one to use in this situation. (If the first character of the “filename” to open is a | , the rest of the argument is treated as a list of arguments to use for building a pipeline.)

链接地址: http://www.djcxy.com/p/64238.html

上一篇: 使用Kinect SDK创建完整的3D骨架

下一篇: tcl执行结果重定向到stdout也需要被存储