![有没有办法让重置命令重置输入设置而不清除屏幕?](https://linux22.com/image/223064/%E6%9C%89%E6%B2%A1%E6%9C%89%E5%8A%9E%E6%B3%95%E8%AE%A9%E9%87%8D%E7%BD%AE%E5%91%BD%E4%BB%A4%E9%87%8D%E7%BD%AE%E8%BE%93%E5%85%A5%E8%AE%BE%E7%BD%AE%E8%80%8C%E4%B8%8D%E6%B8%85%E9%99%A4%E5%B1%8F%E5%B9%95%EF%BC%9F.png)
我的应用程序出现问题,dosemu2 处于-dumb -td -kt
模式下,它与我的 MATE 终端窗口混淆。 (直接在 MATE 终端窗口中,或者在它们之间使用 GNU 屏幕。)在我使用信号 ( killall -v dosemu.bin
) 终止应用程序或使其崩溃后,在此窗口中继续运行的 bash shell 将接收大量文本数据作为 MATE终端窗口接收鼠标光标移动数据。
我发现我可以通过运行命令来恢复 shell 的正常工作reset
,有时也可以只运行tset
.然而,tset
它有时会清除屏幕,有时也不会重置鼠标输入垃圾邮件,这是偶然的。reset
总是重置鼠标输入,但它也总是清除我想避免的屏幕。reset -I
没有清除屏幕,也没有解决鼠标输入问题。
有没有一种方法可以reset
禁用鼠标输入,但不清除可见屏幕区域?
我之前在dosemu2讨论中写过这个问题,在这里:https://github.com/dosemu2/dosemu2/discussions/2061
下面的图像显示了最后以文本形式输入的鼠标数据:
答案1
该reset
命令是 的快捷方式tput reset
。该命令的文档说,
reset
[…] 如果存在的话,终端的重置字符串将被输出(rs1
,rs2
,rs3
,rf
)。如果重置字符串不存在,但存在初始化字符串,则将输出初始化字符串。否则,重置的作用与 init 相同。
因此,为了找出reset
命令实际发送到终端以将其从可能处于的各种模式中切换出来的序列,我们需要查看rs1
、rs2
、rs3
和 的设置rf
。
此时,reset
您可以尝试tput rs1
、 、tput rs2
、 、 和tput rs3
,而不是 ,tput rf
看看哪一个(如果有)可以在不清除屏幕的情况下解决问题。
然而,继续潜水。在man terminfo
文档中简单地写道,
reset_1string rs1 r1 reset string reset_2string rs2 r2 reset string reset_3string rs3 r3 reset string reset_file rf rf name of reset file
这意味着我们需要直接恢复到 terminfo 数据库
infocmp | grep -Po '\w+=[^,]*' | grep -E '^(rs[123]|rf)='
对我来说这会返回两个条目,
rs1=\Ec
rs2=\E[!p\E[?3;4l\E[4l\E>
这些可以用\E
表示直接读取Escape,并重写为printf
序列:
printf '\ec'
printf '\e[!p'; printf '\e[?3;4l'; printf '\e[4l'; printf '\e>'
找出转义序列的实际含义可能超出了这个答案的范围,但这里有一些
ESC c # Reset and clear screen
ESC [!p
ESC [?e;4l
ESC [4l
ESC >
最后,值得注意的是,有一个最近提交自行dosemu
执行必要的重置:
# disable xterm mouse tracking printf '\033[?1006l\033[?1003l\033[?1002l\033[?1000l\033[?9l' # disable xterm cursor keys printf '\033[?1l'
IE
ESC [?1006l ESC [?1003l ESC [?1002l ESC [?1001l ESC ?9l
ESC [?1l