使用巴什,如何将终端应答读入变量而不需要用户交互?下面的一行仍然需要Enter按一次:
echo -ne '\005' && read -s && echo ${REPLY}
另外,我该如何配置Xterm发送一些有意义的回应^E
?到目前为止,我见过的唯一发送任何应答的终端模拟器是油灰。
答案1
应答字符串可在 xterm 中使用以下命令进行配置answerbackString
资源。该资源已添加到1998年。最初返回“xterm”,因为1999年它默认为空字符串,因为一些用户注意到滥用控制序列的可能性,这可能会向计算机发送意外的命令。
其他终端可能始终返回空字符串(konsole、mlterm、vte)。但 rxvt(和 rxvt-unicode)返回意外响应:VT102 的设备属性响应(转义序列)。 PuTTY 返回“PuTTY”(可能是由于 xterm 的早期影响)。
快速检查一下,Linux 控制台显示一个“a”(可能是一个错误)。
由于最初的 VT100 将此作为设置/可配置功能提供,因此仅限于可打印人物。因此,rxvt/urxvt 的响应是出乎意料的。手册页对此做了一个晦涩的评论:
answerbackString
:细绳
指定当 ENQ (control-E) 字符通过时 rxvt-unicode 发送到 shell 的回复。它可能包含转义值,如条目中所述keysym
下列的。
(承诺的描述不存在)。
由于应答字符串的长度未知,因此读取该字符串的应用程序必须允许等待(以防字符在多个读取操作中到达)。当然,还有特定于 ksh/bash 的TMOUT
功能以及命令-t
选项,可以帮助编写 shell 脚本read
。对于一般用途,我避免使用stty
,例如(参见dynamic.sh
):
stty raw -echo min 0 time 5
临时设置终端,使 aread
在 0.5 秒内超时,并允许其返回而不读取任何字符。要了解如何保存/恢复设置,阅读脚本会有所帮助。
进一步阅读:
- 这
vttests
中的脚本xterm
,其中许多读取终端响应字符串。 stty
- 设置终端的选项(POSIX)read
- 从标准输入读取一行(POSIX)
答案2
即使有超时和(某些)要读取的字符数,bash
(version 4.2.46(1)-release
)也可能无法保存REPLY
,这里通过发出“报告光标位置”控制序列,首先输入换行符,然后等待超时:
$ echo -ne '\033[6n' && read -n 16 -s -t 3; echo -n $REPLY | xxd
0000000: 1b5b 3234 3b31 52 .[24;1R
$ echo -ne '\033[6n' && read -n 16 -s -t 3; echo -n $REPLY | xxd
$
这里的问题是-n
大于返回的字节数;如果-n
大小正好正确或更小,则无需输入(或超时)即可读取响应。如果您知道响应字符串的最后一个唯一字符,则可以通过按该字符拆分“行”来获得响应;对于报告字符位置提示,分隔符可以被视为R
:
$ echo -ne '\033[6n' && read -n 999 -d R -s; echo -n $REPLY | xxd
0000000: 1b5b 3234 3b31 .[24;1
$
给定未知长度的未知输入,您必须要么针对 提交错误bash
,要么可能一个接一个乏味地蚕食字节,直到超时触发:
$ out="got "; echo -ne '\033[6n'; while read -n 1 -s -t 1; do out="$out$REPLY"; done
$ echo -n $out | xxd
0000000: 676f 7420 1b5b 3234 3b31 52 got .[24;1R
$
对于control+e我认为的事情终端可以发回一些东西,但必须进行配置才能这样做:
ENQ Return Terminal Status (Ctrl-E). Default response is an empty
string, but may be overridden by a resource answerbackString.