Tcl-在Tcl中无需按enter键即可从标准输入读取字符

Tcl-在Tcl中无需按enter键即可从标准输入读取字符,tcl,channel,Tcl,Channel,我希望在不刷新stdin的情况下,按每个字符读取stdin。在调整了几个小时后,我找不到如何做到这一点。即使在fconfigure stdin-blocking 0-buffering none中,Tcl似乎总是等待刷新通道。这是真的吗?否则我将如何处理这个问题 更多解释: 想象一下,一个Tcl程序通过在后台运行代码的一些线程发出自己的提示。我希望此提示符对单个按键做出反应,例如:当您按“p”(不按enter)时,提示符将读取该字符并暂停线程,当您按“q”时,提示符将终止线程并停止程序。最干净、

我希望在不刷新
stdin
的情况下,按每个字符读取
stdin
。在调整了几个小时后,我找不到如何做到这一点。即使在
fconfigure stdin-blocking 0-buffering none
中,Tcl似乎总是等待刷新通道。这是真的吗?否则我将如何处理这个问题

更多解释:
想象一下,一个Tcl程序通过在后台运行代码的一些线程发出自己的提示。我希望此提示符对单个按键做出反应,例如:当您按“p”(不按
enter
)时,提示符将读取该字符并暂停线程,当您按“q”时,提示符将终止线程并停止程序。最干净、最接近的解决方案将在下面的代码片段中演示

proc readPrompt { } { 
    set in [ read stdin 1 ] 
    if { $in eq "q" } { 
        puts "Quitting..."
        set ::x 1
    } { 
        puts "Given unknown command $in"
    }
}

fconfigure stdin -blocking 0 -buffering none 
fileevent stdin readable { readPrompt }

vwait x
运行此命令的结果是:

a
Given unknown command a
Given unknown command 
按下“a”键后,什么也没发生。我的猜测是
stdin
没有刷新或其他什么。按
enter
CTRL-d
触发文件事件,然后提示读取字符“a”和“
enter

理想情况下,我希望不需要按enter键。我怎样才能做到这一点

编辑:我在Python中找到了一个相关使用的问题和解决方案:这大概是我正在寻找的行为,但在Tcl中是这样的。

如果您有8.7(当前为alpha),那么:

将所有角色传递给您,而不会重复它们。(还有模式
normal
password
,这两种模式都在交付前对数据进行预处理,并且只有一种模式会回显。)您必须亲自向用户提供视觉反馈,并注意所有模式都包括通常仅用于行编辑目的的所有字符

否则,在Unix(Linux、macOS)上,您将执行以下操作:

exec stty raw-echo@stdout
要将模式切换到相同的配置,请执行以下操作:

exec stty -raw echo <@stdin >@stdout
exec stty-raw echo@stdout
换回来。(并非所有Unix都需要输入和输出重定向,但某些Unix确实需要。)



Windows控制台在8.7中有类似的功能,但在以前的版本中没有;可以使用解决方案,但这是一个非常低级的API(我不知道详细信息)。

一些键通常会生成多字符序列。光标键就是这样的例子;这件事做起来如此尴尬,多年来一直困扰着我。如果我有更多的空闲周期,它甚至可能达到8.5…
exec stty raw -echo <@stdin >@stdout
exec stty -raw echo <@stdin >@stdout