首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rebol 2禁用控制台回波

Rebol 2禁用控制台回波
EN

Stack Overflow用户
提问于 2016-03-21 21:37:52
回答 2查看 328关注 0票数 4

我有一个Rebol2控制台应用程序(Rebol Core),我想禁用控制台的键盘字符回显。该应用程序由最小的Linux内核/initramfs运行,并由busybox inittab启动(而不是从终端启动)。它有一个最小的控制台用户界面使用ansi代码的颜色等,并响应菜单选择通过单键按。为了使控制台“安静”,我关闭了光标,并且直到最近才看到按键的输出。

我以前以为通过在Rebol中调用'stty -echo‘来解决问题,但是它实际上并不像我刚才发现的那样工作--有一个函数需要5-10秒,在等待函数完成时可以看到回显的按键。

我不太清楚为什么在这个函数运行时只看到回显字符,但它是唯一需要花费大量时间的函数。通过打开控制台://在二进制模式下,等待按下键,然后用开关语句选择函数来轮询键盘。读取二进制/控制台中的键似乎“消耗”了键echo-

代码语言:javascript
复制
minimal example, pressing 'a'-

    cons: open/binary console://
    first cons
    == 97

(返回的值是我想要的,而char没有回显,这很好-我认为在大多数函数中,我的键在get-key循环中被“消耗”了,但是越长的函数就没有机会“消耗”它们,并最终回音到控制台)

有什么方法可以禁用Rebol2内部的控制台字符回显吗?我查看了系统/控制台和系统/端口/输入、输出,但没有看到任何明显的结果。我目前的解决办法是简单地更改文本颜色以匹配背景,以便在特定函数运行时任何按键都是不可见的。

下面是我所做的最简单的例子-

代码语言:javascript
复制
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键之间的时间很短。我还要注意的是,在随后调用get-key时,回显字符也不会出现。

更新-

这里有一个更好的代码示例来查看问题-

代码语言:javascript
复制
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 ]
  ]
]

我发现我的“long”函数是使用call's,它可能需要几秒钟时间,所以当使用一个调用时,问题就出现了。

上面的代码,当运行时,将显示键被回显,仅仅是因为它们被打印在get-key函数(括号)中;当长-func运行时,则键被回显在get-key之外(没有括号),当完成时,get-key也会处理这些键。或者,只需运行' call /wait {休眠10}‘,您将在等待时得到回显的键,并在调用返回时得到由Rebol回显的sames键。当reb-func运行时,键不会回显,在reb-func完成时,get-key将处理所有缓冲键。当使用call时,键盘输入将被处理两次。

我已经尝试过重定向call命令中的stdin/stdout (在调用字符串命令中,类似于bash提示符),但是没有找到起作用的组合体。(我的实际代码运行带有/output/error的调用来捕获所有输出)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-30 18:58:20

重新排列的控制台代码是不必要的(并且所有的键都被缓存,不管使用哪种排列),尽管添加唤醒函数的能力是很好的。在我的实际代码中,get-key有一个'/timeout t‘选项,在这里我可以执行一个“等待参数t”并返回一个字符串(对于像向上箭头这样的扩展键代码)或“无”,这意味着我也可以在我的开关获得键之前刷新控制台输入(因此在运行函数时按下的任何键都会被刷新)。

代码语言:javascript
复制
forever [
  while [ get-key/timeout 0.1 ][] ;flush
  switch get-key [ ;wait for key
...

在给出的示例中,'stty -echo‘工作得很好,并且似乎解决了我的问题,但是当长函数运行时按下一串键(我在所有命令中插入了{stty -echo;}),我仍然可以看到一些字符的回响。不知何故,在Rebol调用创建进程(我假设为叉/exec)中,tty输入/输出仍然可以“泄漏”i/o字符。或者,其中一个被调用的程序正在打开tty,即使它继承了父程序的文件描述符。

下面是我最后所做的事情--改变我调用命令的方式,使它们在后台运行,但仍然等待它们完成。

代码语言:javascript
复制
;used by other funcs to parse output of commands
set 'cmd-output "" ;output from 'call' commands
set 'cmd-error "" ;error from 'call commands

set 'cmd func [ str [string!] /local ret ][
  --old--
  ;clear previous
  cmd-output: copy ""
  cmd-error: copy ""

  ;--new--
  write %out ""
  write %err ""
  attempt [ delete %ret ]

  ;--old--
  ;ret: call/wait/output/error str cmd-output cmd-error

  ;--new--  stdout->out stderr->err exitcode->ret
  call rejoin [ str { >out 2>err; echo -n $? > ret} ]
  ;wait for return code, (up to 20 seconds, should be plenty)
  loop 200 [ all [ exists? %ret  break ] wait 0.1 ]
  cmd-output: read %out
  cmd-error: read %err
  ret: to-integer read %ret

  --old--
  ;debug-cmd writes info to a logfile
  debug-cmd str ret
  ret
]

这是可行的,因为我无法像以前一样在屏幕上显示任何(不想要的)字符(我猜这证明了这些字符来自被调用的进程)。

票数 1
EN

Stack Overflow用户

发布于 2016-03-22 22:06:28

如果不通过等待端口和唤醒函数来优化代码,我想您的问题可以通过在get-key函数之外放置打开和关闭控制台端口来解决,如

代码语言:javascript
复制
get-key: func [ /local ch ][
    ch: lowercase to-string to-char first cons
    all [ equal? ch "^["   append ch copy/part cons 2 ]
    ch
]
cons: open/binary [scheme: 'console]
forever [
    switch get-key [
        ;up arrow
        "^[[A" [ some-function1 ]
        ;down arrow
        "^[[B" [ some-function2 ]
        ;enter
        "^M" [ some-function3 ]
        ;quit
        "q" [ break ]
    ]
]
close cons

好的,下面是一个优化版本,包括您的第二个示例

代码语言:javascript
复制
long-func: does [ call/wait {stty -echo ; sleep 10} ]
reb-func: does [ wait 10 ]

 cons: open/binary [scheme: 'console]
 cons/awake: func [port] [
    key: to-char first port
    print ["<" key ">"]
    switch key [
        #"f" [long-func]
        #"r" [reb-func]
        #"q" [break]
    ]
 ]
forever [ 
    wait [cons]
]

你可以看到,所有的键都是按下的,没有额外的回声。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36142105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档