首页 > 解决方案 > If 构造中的中断条件

问题描述

嗨,我正在使用这段代码在 TCL 中插入管道。[gets $pipe line] >= 0当这种情况失败时,任何人都可以让我理解。例如:只有当[gets $pipe line]是负数时才会失败。

在我的情况下,它永远不会返回负数,并且 TestEngine 永远挂起

set pipeline [open "|Certify.exe filename" "r+"]
fileevent $pipeline readable [list handlePipeReadable $pipeline]
fconfigure $pipeline -blocking 0

proc handlePipeReadable {pipe} {
    if {[gets $pipe line] >= 0} {
        # Managed to actually read a line; stored in $line now
    } elseif {[eof $pipe]} {
        # Pipeline was closed; get exit code, etc.
        if {[catch {close $pipe} msg opt]} {
            set exitinfo [dict get $opt -errorcode]
        } else {
            # Successful termination
            set exitinfo ""
        }
        # Stop the waiting in [vwait], below
        set ::donepipe $pipe
    } else {
        puts ""
        # Partial read; things will be properly buffered up for now...
    }
}

vwait ::donepipe

标签: tcl

解决方案


gets命令(当给定一个变量来接收该行时)在小错误条件下返回一个负数。有两个这样的条件:

  1. 当通道到达文件结尾时。gets这种情况下,该命令eof(应用于通道)将报告一个真值。
  2. 当通道被阻塞时,即当它有一些字节但不是一个完整的行时(Tcl 有内部缓冲来处理这个问题;你可以用 获取待处理的字节数chan pending)。只有当通道处于非阻塞模式时才会看到这一点(因为否则gets会无限期地等待)。在这种情况下,fblocked命令(应用于通道)将返回 true。

主要错误条件(例如通道被关闭)会导致 Tcl 错误。


如果另一个命令只产生部分输出或做一些奇怪的缓冲,你会得到一个永远阻塞的管道。更有可能使用双向管道,例如您正在使用的,因为该Certify命令可能正在等待您关闭另一端。你能以只读方式使用它吗?双向正确地与进程交互有很多复杂性!(例如,您可能希望将管道的输出缓冲模式设为无缓冲,fconfigure $pipeline -buffering none.)


推荐阅读