![从终端读取,无需等待](https://linux22.com/image/182772/%E4%BB%8E%E7%BB%88%E7%AB%AF%E8%AF%BB%E5%8F%96%EF%BC%8C%E6%97%A0%E9%9C%80%E7%AD%89%E5%BE%85%20.png)
很抱歉用这么愚蠢的问题打扰您,但我最近开始使用 Linux 终端,当我阅读一篇有关该命令的论文时,stty
我发现了以下问题:
¿如何更改回显并读取而无需等待ENTER(只需输入从“0”到“f”的十六进制数字)?
我知道第一部分stty -echo
和stty 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/0
read()
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
内置默认情况下不会更改终端设备设置,因此仍然需要等待来自终端设备的任何内容。gmacs
vared
zsh
read -e
read
Enter
然而,read
zsh 的内置功能(带有-k
或-q
选项)以及 ksh93、bash 或 mksh(带有-n
或-N
选项)的内置功能将禁用该icanon
模式,以便在从终端设备获取输入时能够通过单个按键返回(isig
不是但已禁用,因此您仍然可以中断脚本(Ctrl+C例如)。