从终端读取,无需等待

从终端读取,无需等待

很抱歉用这么愚蠢的问题打扰您,但我最近开始使用 Linux 终端,当我阅读一篇有关该命令的论文时,stty我发现了以下问题:

¿如何更改回显并读取而无需等待ENTER(只需输入从“0”到“f”的十六进制数字)?

我知道第一部分stty -echostty echo

但我不知道如何在不等待的情况下从终端读取ENTER。我一直在man第二个搜索中进行搜索,但在命令中找不到stty实现此目的的设置。

我知道它应该很简单,但我找不到添加输入十六进制数字的解决方案或逻辑。

答案1

如果您指的是 read -- shell 内置命令,那么它可以选择在读取 N 个字符后返回,而不是等待 ENTER。尝试:

read -n1 ; echo You entered $REPLY

还,read --help

答案2

您需要按 的原因Enter是终端设备驱动程序(/dev/tty*/dev/pt*设备背后的内核代码,而不是与您交互的带有键盘和显示器的物理设备)实现了基本的行编辑器。

例如,当应用程序read()对打开的文件描述符进行系统调用时,当您按 Enter 键(并且使用CR当您按转换为 LF 时终端发送的字符)。/dev/pts/0read()BackspaceCtrl+UCtrl+WEnter

要禁用该行编辑器,您需要向该设备驱动程序发出特定的控制指令。这就是stty命令发挥作用的地方。

使用 时stty -icanon,该行编辑器被禁用(stty cbreak某些系统需要它,您会发现stty cbreak它通常被支持作为替代方案)。

当不在该icanon模式下时,一些其他参数用于自定义直接的模式:

  • ^C^Z仍然导致中断/挂起。您需要stty -isig禁用它们,以便它们按原样传递到阅读应用程序。
  • ^Q^S仍然用于流量控制(stty -ixon禁用)。
  • CR仍会转换为LF,您需要stty -icrnl禁用它。

stty raw是禁用所有这些和某些的快捷方式输出处理也是如此。如果最重要的是,您添加一个-echo,那么您的/dev/pts/1设备就像终端和与其交互的应用程序之间的普通传递一样。

所以:

saved_settings=$(stty -g)
stty raw -echo
byte=$(dd bs=1 count=1 2> /dev/null)
stty "$saved_settings"

将准备好一份字节(不是字符,更不用说您的终端在按下某些按键时可能发送的字符序列)一旦由您的终端发送,就从终端设备发送。

除了 ksh 中(当vi//选项位于 ksh 实现其自己的行编辑器的位置时,请参阅或bash中的等效项),emacs内置默认情况下不会更改终端设备设置,因此仍然需要等待来自终端设备的任何内容。gmacsvaredzshread -ereadEnter

然而,readzsh 的内置功能(带有-k-q选项)以及 ksh93、bash 或 mksh(带有-n-N选项)的内置功能将禁用该icanon模式,以便在从终端设备获取输入时能够通过单个按键返回(isig不是但已禁用,因此您仍然可以中断脚本(Ctrl+C例如)。

相关内容