Stephane Asked: 2022-02-03 00:39:51 +0800 CST2022-02-03 00:39:51 +0800 CST 2022-02-03 00:39:51 +0800 CST 如何清除键盘缓冲区? 772 假设一个应用程序要求键盘输入,我按住一个键一会儿。 现在应用程序正在响应按键,但随着进程的进行而变慢。 这个想法是清除所有这些传入的按键,存储在缓冲区的某个位置,以便让应用程序停止它做得不好的事情。 linux 2 个回答 Voted Best Answer Frédéric Loyer 2022-02-03T01:17:58+08:002022-02-03T01:17:58+08:00 您必须指明应用程序的类型:终端(POSIX 系统调用、curses 或 stdio API)、Qt、Gtk... 如果它是一个终端(系统调用),您可以使用select系统调用并验证标准输入上是否有可用的东西,如果是真的,请阅读它。 这更像是一个编程问题。 correabuscar 2022-10-13T03:22:45+08:002022-10-13T03:22:45+08:00 我将How to clear the keyboard buffer?在某种意义上回答标题问题,即到目前为止键入的所有内容并被视为等待程序使用它的输入,都将被清除,这就是我在可执行文件中的操作方式( ie. chmod a+x clrbuf) 被调用clrbuf,它默默地消耗输入: #!/bin/bash read -r -t 0.1 -s -e -- stty echo echok exit 0 说明: tl;dr:静默消耗所有输入,如果没有输入,则在 0.1 秒(100 毫秒)后退出,然后用于stty确保read没有禁用用户键入内容的回显,这可能在某些情况下发生案例。 这是使用 /bin/bash 的内部read命令(即$ help read在bashshell 中尝试,或查看此文档)并使用 /bin/stty 这是 coreutils 包的一部分(在 Gentoo 上)。 它将读取所有等待读取的内容并忽略它。 例如,如果您运行,sleep 5 ; clrbuf然后您开始输入类似hello+enter 键并停止输入,然后在 5 秒后clrbuf运行并吃掉您输入的内容,因此之后的终端提示不会获得该输入。像这样: $ sleep 5; clrbuf hello $ sleep 5; notclrbuf hello bash: notclrbuf: command not found $ hello bash: hello: command not found 的论点read:不需要,它标志着所有论点的结束,这对我来说只是一个习惯。-- $ read -r -- $ read -- -r bash: read: `-r': not a valid identifier 因为它需要一个变量标识符来放置读取的结果。 -r “不允许反斜杠转义任何字符。反斜杠不充当转义字符。反斜杠被认为是行的一部分。特别是,反斜杠换行对不能用作行继续。” help read(来自那个文档) $ read -- a ; echo $a \\ \ $ read -r -- a ; echo $a \\ \\ -t TIMEOUT “如果在 TIMEOUT 秒内未读取完整的输入行,则导致读取超时并返回失败。如果读取不是从终端或管道读取输入,则此选项无效。”(来自同一文档)。-t 0.1用于在 0.1 秒后自动退出,read当没有输入待处理时。 -s “静默模式。如果输入来自终端,则不会回显字符。”(来自同一个文档) 例如,如果我键入“hi”+enter,则一次: $ sleep 5; read -r -t 0.1 -e -- hi hi $ sleep 5; read -r -t 0.1 -s -e -- hi -e “readline 用于获取行”。出于某种原因,我注意到没有这个论点它是行不通的。我不记得为什么,但我注意到“GNU bash,版本 5.0.16(1)-maint (x86_64-pc-linux-gnu) commit 3235014e5b3d227ccd617b0be72d897eb476d23d on devel branch 日期:4 月 20 日星期一 10:11:53 2020 -0400”。值得一提的是,我在 Gentoo 上使用 USE=bundled-readline 编译了 bash,也许这就是为什么它-e目前对我来说仍然有效。我不确定。 exit 0是始终确保从脚本返回成功,以防万一clrbuf在另一个 bash 脚本中使用set -e(如果在调用脚本后发生不同于 0 的退出代码,这将导致该脚本退出clrbuf)(“ -e 立即退出如果命令以非零状态退出。")。例子: #!/bin/bash set -e test 20 == 0 #^ our script will exit due to the above, because the above returned exit code 1 echo Done #^ this is not reached 为什么stty echo echok需要? 由于read -s(又名静默)相当于stty -echo -echok(即禁用echo和echok),为了确保用户永远不会无法回显键入的内容,在某些情况下,我们确保回显完成后启用read -s。 以下示例 (c.bash) 说明了何时可能发生这种情况: #!/bin/bash stty for i in 1 2 3 4; do echo 'a' & #required read -r -t 0.1 -s -- & #echo "$?" #is 0 done wait stty stty echo echok 输出是这样的: $ ./c.bash speed 38400 baud; line = 0; erase = ^H; -brkint -imaxbel iutf8 a a a a speed 38400 baud; line = 0; erase = ^H; -brkint -imaxbel iutf8 -echo -echok 正如您在最后看到的那样,与在启用它们时-echo -echok调用之前相比read -s ... &(因此 stty 根本不打印),设置了新的东西(禁用)。最后一行stty echo echok将确保启用它们(请注意,它们缺少减号 ( -) 前缀),否则之后您将看不到您在命令提示符下键入的内容(即禁用回显您键入的内容)脚本退出。 请注意,此示例不是进入此状态的唯一方法,但它是一个示例,它帮助我重现了当我只使用readto时禁用 echo 的问题clrbuf,而没有stty. 更好的方法可能是在调用之前保存echoand的状态,然后再恢复状态。但这很容易出现竞争条件(如果禁用回声的程序在我们的并行期间重新启用它们),因此可能会给用户留下不可回声的终端(当我们将它们恢复为禁用时)。就个人而言,我不会冒险实施这个变体。echokread -s ...read -sstty
您必须指明应用程序的类型:终端(POSIX 系统调用、curses 或 stdio API)、Qt、Gtk...
如果它是一个终端(系统调用),您可以使用
select
系统调用并验证标准输入上是否有可用的东西,如果是真的,请阅读它。这更像是一个编程问题。
我将
How to clear the keyboard buffer?
在某种意义上回答标题问题,即到目前为止键入的所有内容并被视为等待程序使用它的输入,都将被清除,这就是我在可执行文件中的操作方式( ie.chmod a+x clrbuf
) 被调用clrbuf
,它默默地消耗输入:说明:
tl;dr:静默消耗所有输入,如果没有输入,则在 0.1 秒(100 毫秒)后退出,然后用于
stty
确保read
没有禁用用户键入内容的回显,这可能在某些情况下发生案例。这是使用 /bin/bash 的内部
read
命令(即$ help read
在bash
shell 中尝试,或查看此文档)并使用 /bin/stty 这是 coreutils 包的一部分(在 Gentoo 上)。它将读取所有等待读取的内容并忽略它。
例如,如果您运行,
sleep 5 ; clrbuf
然后您开始输入类似hello
+enter 键并停止输入,然后在 5 秒后clrbuf
运行并吃掉您输入的内容,因此之后的终端提示不会获得该输入。像这样:的论点
read
:不需要,它标志着所有论点的结束,这对我来说只是一个习惯。--
因为它需要一个变量标识符来放置读取的结果。
-r
“不允许反斜杠转义任何字符。反斜杠不充当转义字符。反斜杠被认为是行的一部分。特别是,反斜杠换行对不能用作行继续。”help read
(来自那个文档)-t TIMEOUT
“如果在 TIMEOUT 秒内未读取完整的输入行,则导致读取超时并返回失败。如果读取不是从终端或管道读取输入,则此选项无效。”(来自同一文档)。-t 0.1
用于在 0.1 秒后自动退出,read
当没有输入待处理时。-s
“静默模式。如果输入来自终端,则不会回显字符。”(来自同一个文档)例如,如果我键入“hi”+enter,则一次:
-e
“readline 用于获取行”。出于某种原因,我注意到没有这个论点它是行不通的。我不记得为什么,但我注意到“GNU bash,版本 5.0.16(1)-maint (x86_64-pc-linux-gnu) commit 3235014e5b3d227ccd617b0be72d897eb476d23d on devel branch 日期:4 月 20 日星期一 10:11:53 2020 -0400”。值得一提的是,我在 Gentoo 上使用 USE=bundled-readline 编译了 bash,也许这就是为什么它-e
目前对我来说仍然有效。我不确定。exit 0
是始终确保从脚本返回成功,以防万一clrbuf
在另一个 bash 脚本中使用set -e
(如果在调用脚本后发生不同于 0 的退出代码,这将导致该脚本退出clrbuf
)(“ -e 立即退出如果命令以非零状态退出。")。例子:为什么
stty echo echok
需要?由于
read -s
(又名静默)相当于stty -echo -echok
(即禁用echo
和echok
),为了确保用户永远不会无法回显键入的内容,在某些情况下,我们确保回显完成后启用read -s
。以下示例 (c.bash) 说明了何时可能发生这种情况:
输出是这样的:
正如您在最后看到的那样,与在启用它们时
-echo -echok
调用之前相比read -s ... &
(因此 stty 根本不打印),设置了新的东西(禁用)。最后一行stty echo echok
将确保启用它们(请注意,它们缺少减号 (-
) 前缀),否则之后您将看不到您在命令提示符下键入的内容(即禁用回显您键入的内容)脚本退出。请注意,此示例不是进入此状态的唯一方法,但它是一个示例,它帮助我重现了当我只使用
read
to时禁用 echo 的问题clrbuf
,而没有stty
.更好的方法可能是在调用之前保存
echo
and的状态,然后再恢复状态。但这很容易出现竞争条件(如果禁用回声的程序在我们的并行期间重新启用它们),因此可能会给用户留下不可回声的终端(当我们将它们恢复为禁用时)。就个人而言,我不会冒险实施这个变体。echok
read -s ...
read -s
stty