TCL脚本 - exec将文本刷新到我的标准输出

时间:2016-02-14 20:55:14

标签: pipe tcl exec stdout

我怎样才能"冲洗" stdout命令的exec到我的脚本stdout没有"等待"为了得到的exec返回?

例如,在以下脚本中,我希望git clone输出立即显示在我的脚本上下文中:

#!/usr/bin/tclsh

# git outputs progress of the clone download but it isn't visible in this script's context. How can I flush it? 
exec git clone /path/to/some/repo.git

我猜我需要某种pipe "|"tee的组合以及文件重定向。 似乎没能做对。

3 个答案:

答案 0 :(得分:4)

要立即获取输出,您需要将子命令作为管道打开。正确的(而不是相当显而易见,为此我们道歉)这样做的方法是使用clear;save=$(fortune);cowsay -f gnu <<< "$save"; espeak <<< "$save" 的这种结构:

open |[list …]

请注意,某些程序(我不知道set mypipeline [open |[list git clone /path/to/some/repo.git]] # Now to read it by line; we'll just print it out with a line number to show off set linenum 0 while {[gets $mypipeline line] >= 0} { puts "Line [incr linenum]: $line" } # Close the pipe now we're at EOF close $mypipeline 是否为1)在管道中运行时会改变它们的行为,缓冲它们的输出直到它们具有完整的缓冲区值。 (当输出不是终端时,它是C运行时默认工作方式的一部分。)如果这是一个问题,则必须使用Expect运行。这是一个足够大的话题,你应该寻找(并在必要时提出)一个单独的问题;这是复杂性的一个很大的变化,唉。

另外请注意,git可能会写入其标准错误(如本问题Reading output of git push from PHP exec() function中所述),因此您可能需要将标准错误合并到捕获的标准错误中(如{{3}中简要记录的那样手册页)。

git
set output [exec git clone /path/to/some/repo.git 2>@1]

也可以执行读/写管道,但更复杂。

答案 1 :(得分:0)

exec的工作是捕获命令的输出,所以我不认为你可以改变它的缓冲。这里的测试在交互式tclsh会话中得到了最好的说明:这两个命令都等到执行过程完成后再返回输出,即使是我明确要求行缓冲的那个

exec sh -c {sleep 2; echo a; sleep 2; echo b; sleep 3; echo c}
exec stdbuf --output=L sh -c {sleep 2; echo a; sleep 2; echo b; sleep 3; echo c}

您必须打开命令管道,然后逐行读取输出。这将显示上述命令的输出:

set pipe [open [list "|" sh -c {sleep 2; echo a; sleep 2; echo b; sleep 3; echo c}] r]
while {[gets $pipe line] != -1} {puts $line}
close $pipe

当你说它在这个剧本的背景下不可见时,你是什么意思&#34;?回想一下exec 捕获输出。默认情况下不打印。我想知道你是否只想要

puts [exec git clone /path/to/some/repo.git]

但是,如果你想在&#34;实时&#34;中看到文字,请打开一个管道并在gets上循环,如图所示。

答案 2 :(得分:0)

如果您对TCL程序中程序的输出不感兴趣,则也可以使用exec命令的'> @'选项将输出重定向到其他位置,例如,您的情况。