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

Nar*_*rek 7 stdout tcl exec

湖看看这两条线

情况1

set cvsUpdStr [exec cvs -qn upd]
Run Code Online (Sandbox Code Playgroud)

案例2

set cvsUpdStr [exec cvs -qn upd >&@stdout]
Run Code Online (Sandbox Code Playgroud)

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

Don*_*ows 5

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

\n\n
# I like to spell out \xe2\x80\x9cupdate\xe2\x80\x9d in full\nset cvsUpdStr [exec cvs -qn update | tee /dev/tty]\n
Run Code Online (Sandbox Code Playgroud)\n\n

程序tee将其标准输入发送到其正常的标准输出以及指定的文件;我们用/dev/tty将其发送到当前终端。

\n\n

但请注意,您的输出可能会出现较长的延迟cvs但请注意,由于它缓冲其输出这只是 C 库在将输出发送到非终端时 I/O 处理的默认行为,如果您立即需要输出,这可能会成为问题。修复这个问题非常复杂(你最终会使用 Expect),所以如果你对突发的输出感到满意,就不要管它\xe2\x80\xa6

\n\n
\n\n

在 Windows 上,您需要以另一种方式进行操作。

\n\n
set pipe [open |[list cvs -qn update] "r"]\nwhile {[gets $pipe line] >= 0} {\n    append cvsUpdStr "$line\\n"   ;# Note the \\n at the end!\n    puts $line\n}\nclose $pipe                      ;# Any errors turn up here!\n
Run Code Online (Sandbox Code Playgroud)\n\n

with 的结构|[list ...]在 Tcl 术语中相当不寻常,但在这种情况下使用它是正确的。(如果 \xe2\x80\x9c 文件名\xe2\x80\x9d 的第一个字符open是 a |则其余字符将被视为用于构建管道的参数列表。)

\n