如何检查stdin在TCL中是否可读?

如何检查stdin在TCL中是否可读?,tcl,stdin,gets,readable,Tcl,Stdin,Gets,Readable,使用以下命令,您可以为stdin注册一些回调: fileevent stdin readable thatCallback 这意味着在执行update命令的过程中,当在stdin上有可用的输入时,它将一次又一次地计算thatCallback 如何检查stdin中的输入是否可用?您只需在回调中读取stdin中的内容即可。基本上,该模式类似于以下代码片段: 如果查看问题的答案,您可以看到如何使用fconfigure将通道置于非阻塞模式。关于此Tcl手册有更多详细信息,您需要将fconfigure手

使用以下命令,您可以为
stdin
注册一些回调:

fileevent stdin readable thatCallback
这意味着在执行update命令的过程中,当在
stdin
上有可用的输入时,它将一次又一次地计算
thatCallback


如何检查stdin中的输入是否可用?

您只需在回调中读取stdin中的内容即可。基本上,该模式类似于以下代码片段:


如果查看问题的答案,您可以看到如何使用fconfigure将通道置于非阻塞模式。关于此Tcl手册有更多详细信息,您需要将fconfigure手册页面与vwait手册页面一起查看。

问题在于此。在
stdin
上有一个输入,我想读取该输入。我可以用
gets
命令逐行读取它,但是最后一个
gets
将挂起并等待输入。在上面的代码中,情况是相同的。不,重要的部分是“fconfigure-blocking false”。我不认为在任何情况下,
获得
的成功值为负值,但
eof
fblocked
都是false。我认为其他问题案例要么直接在IO库中处理,要么反映为
get
中的错误。如果
fconfigure-blocking false
,则
gets
将不会挂起。但在这种情况下,如果输入不以换行符结尾,则不会读取输入的最后一部分(从最后一个换行符到输入结尾的部分)。这就引出了另一个问题:
proc isReadable { f } {
  # The channel is readable; try to read it.
  set status [catch { gets $f line } result]
  if { $status != 0 } {
    # Error on the channel
    puts "error reading $f: $result"
    set ::DONE 2
  } elseif { $result >= 0 } {
    # Successfully read the channel
    puts "got: $line"
  } elseif { [eof $f] } {
    # End of file on the channel
    puts "end of file"
    set ::DONE 1
  } elseif { [fblocked $f] } {
    # Read blocked.  Just return
  } else {
    # Something else
    puts "can't happen"
    set ::DONE 3
  }
}
# Open a pipe
set fid [open "|ls"]

# Set up to deliver file events on the pipe
fconfigure $fid -blocking false
fileevent $fid readable [list isReadable $fid]

# Launch the event loop and wait for the file events to finish
vwait ::DONE

# Close the pipe
close $fid