你有问题的关键是这一行:
fileevent $pipe readable "set ::compress_result [gets $pipe line]"
这读取来自管的管线立即因为[gets …]
是在双引号的字符串。更改为:
fileevent $pipe readable {set ::compress_result [gets $pipe line]}
使事情工作,因为它推迟从管道的读数,直到管道变得可读。但是,要这样做,它依赖于pipe
变量是全局变量。它实际上是更好地做到这一点:
fileevent $pipe readable [list apply {pipe {
global compress_result
set compress_result [gets $pipe line]
}} $pipe]
这是相当丑陋,笨拙的调试,所以我们反而实际上使用一个辅助程序:
proc pipedone {pipe} {
global compress_result
set compress_result [gets $pipe line]
}
fileevent $pipe readable [list pipedone $pipe]
这里使用的list
做“引用这作为以后的可运行脚本“,以应对您在变量中可能遇到的任何意想不到的技巧。它知道如何正确引用事情,所以你不必这样做。
在Tcl 8.6中,你最好使用协程。
coroutine piperead apply {{tar folder} {
# Open the pipe
set pipe [open |[list $tar -cf $folder.tar $folder] "r"]
# Wait until readable
fileevent $pipe readable [info coroutine]
yield
# Read and close
set return_result [gets $pipe line]
close $pipe
return $return_result
}} $tar_executable $folder_to_tar
在我潜入之前,有没有使用'r +'模式的理由?我期望'r'(这实际上是可省略的,因为它是默认值)。 –
这就是我从tcl wiki复制而来的。哈哈。 – TheBat