Tcl - 从标准输入中读取字符而无需在 Tcl 中按回车
Tcl - Reading characters from stdin without having to press enter in Tcl
我想在不刷新 stdin
的情况下按字符读取 stdin
。调整了几个小时后,我找不到如何做到这一点。即使在 fconfigure stdin -blocking 0 -buffering none
中,Tcl 似乎总是等待通道被刷新。真的吗?否则我该如何处理?
更多解释:
想象一个 Tcl 程序在后台使用一些线程 运行 代码生成自己的提示。我希望此提示对单个击键做出反应,例如:当您按 'p'(不按 enter
)时,提示会读取该字符并暂停线程,当您按 'q' prompt 杀死线程并停止程序。最干净和最接近的解决方案在以下代码片段中进行了简短演示。
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
-press。我怎样才能做到这一点?
编辑:我在 Python 中找到了有关相关用途的问题和解决方案: 这大约是我正在寻找的行为,但在 Tcl 中。
如果你有 8.7(目前处于 alpha 阶段)那么 this is “trivial”:
fconfigure stdin -inputmode raw
这会向您传送 所有 个字符,而不回显它们。 (还有模式 normal
和 password
,这两种模式都在传送前对数据进行预处理,并且只有一种模式会回显。)您必须自己注意向用户提供视觉反馈,并注意所有 包括通常仅用于行编辑目的的所有字符。
否则,在 Unixes(Linux、macOS)上你会:
exec stty raw -echo <@stdin >@stdout
将模式切换到相同的配置,并且:
exec stty -raw echo <@stdin >@stdout
切换回来。 (并非所有 Unix 都需要输入和输出重定向,但有些确实需要。)
Windows 控制台在 8.7 中有类似的东西,但在以前的版本中没有;使用 TWAPI console support 可能有解决方法,但这是一个非常低的级别 API(我不知道细节)。
我想在不刷新 stdin
的情况下按字符读取 stdin
。调整了几个小时后,我找不到如何做到这一点。即使在 fconfigure stdin -blocking 0 -buffering none
中,Tcl 似乎总是等待通道被刷新。真的吗?否则我该如何处理?
更多解释:
想象一个 Tcl 程序在后台使用一些线程 运行 代码生成自己的提示。我希望此提示对单个击键做出反应,例如:当您按 'p'(不按 enter
)时,提示会读取该字符并暂停线程,当您按 'q' prompt 杀死线程并停止程序。最干净和最接近的解决方案在以下代码片段中进行了简短演示。
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
-press。我怎样才能做到这一点?
编辑:我在 Python 中找到了有关相关用途的问题和解决方案:
如果你有 8.7(目前处于 alpha 阶段)那么 this is “trivial”:
fconfigure stdin -inputmode raw
这会向您传送 所有 个字符,而不回显它们。 (还有模式 normal
和 password
,这两种模式都在传送前对数据进行预处理,并且只有一种模式会回显。)您必须自己注意向用户提供视觉反馈,并注意所有 包括通常仅用于行编辑目的的所有字符。
否则,在 Unixes(Linux、macOS)上你会:
exec stty raw -echo <@stdin >@stdout
将模式切换到相同的配置,并且:
exec stty -raw echo <@stdin >@stdout
切换回来。 (并非所有 Unix 都需要输入和输出重定向,但有些确实需要。)
Windows 控制台在 8.7 中有类似的东西,但在以前的版本中没有;使用 TWAPI console support 可能有解决方法,但这是一个非常低的级别 API(我不知道细节)。