我怎样才能"冲洗" 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
的组合以及文件重定向。
似乎没能做对。
答案 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命令的'> @'选项将输出重定向到其他位置,例如,您的情况。