我有一个 Rebol2 控制台应用程序(Rebol Core),我想禁用键盘字符回显到控制台。该应用程序从最小的 Linux 内核/initramfs 运行,并由busybox inittab(不是从终端)启动。它有一个最小的控制台用户界面,使用 ansi 代码来表示颜色等,并通过单键响应菜单选择。为了使控制台“安静”,我关闭了光标,并且看不到按键的输出(直到最近)。
我以前认为我通过在 Rebol 中调用 'stty -echo' 解决了问题,但它实际上并没有像我刚刚发现的那样工作 - 有一个函数需要 5-10 秒并且可以在等待时看到回显的按键功能来完成。
我不太清楚为什么在这个函数运行时我只看到回显字符,但它是唯一需要任何时间的函数。通过以二进制模式打开 console:// 来轮询键盘,等待按键,然后使用 switch 语句来选择功能。二进制/控制台中键的读取似乎“消耗”了键回显-
minimal example, pressing 'a'-
cons: open/binary console://
first cons
== 97
(值按我的意愿返回,并且 char 没有回显,这很好——我认为在大多数函数中,我的键在 get-key 循环中被“使用”,但较长的函数没有机会“使用” ' 他们,并最终回声到控制台)
有什么方法可以禁用 Rebol2 中的控制台字符回显吗?我查看了系统/控制台和系统/端口/输入、输出,但没有看到任何明显的东西。我目前的解决方法是简单地更改文本颜色以匹配背景,以便在特定功能运行时任何按键都不可见。
这是我正在做的一个最小的例子-
get-key: func [ /local cons ch ][
cons: open/binary console://
ch: lowercase to-string to-char first cons
all [ equal? ch "^[" append ch copy/part cons 2 ]
close cons
ch
]
forever [
switch get-key [
;up arrow
"^[[A" [ some-function1 ]
;down arrow
"^[[B" [ some-function2 ]
;enter
"^M" [ some-function3 ]
;quit
"q" [ break ]
]
]
永远循环似乎“消耗”了键盘输入(没有回显),但如果其中一个功能需要任何时间,任何键盘输入都会在光标所在的位置回显到屏幕上。在大多数情况下,我从来没有看到任何回显字符,因为调用 get-key 之间的时间很短。我还要注意,回显的字符也不会出现在随后的 get-key 调用中。
更新-
这是一个更好的代码示例来查看问题-
get-key: has [ cons ch ][
cons: open/binary console://
ch: lowercase to-string to-char first cons
prin rejoin [ "<" ch ">" ] ;show get-key chars
ch
]
long-func: does [ call/wait {sleep 10} ]
reb-func: does [ wait 10 ]
forever [
switch get-key [
"f" [ long-func ]
"r" [ reb-func ]
"q" [ break ]
]
]
我发现我的“长”函数正在使用调用,这可能需要几秒钟,所以在使用调用时会出现问题。
上面的代码,在运行时将显示键被回显,只是因为它们被打印在 get-key 函数(括号)中,当 long-func 运行时,键在 get-key 之外被回显(没有括号),并且完成后,get-key 也会处理这些密钥。或者简单地运行'call/wait {sleep 10}',你会在等待时得到回显键,并且在调用返回时也会得到 Rebol 回显的相同键。reb-func 运行时不会回显键,并且 get-key 将在 reb-func 完成时处理所有缓冲的键。使用呼叫时,键盘输入被处理两次。
我尝试在调用命令中重定向标准输入/标准输出(在调用字符串命令中,如在 bash 提示符下),但没有找到有效的组合。(我的实际代码使用 /output/error 运行调用以捕获所有输出)。