QEMU 是让我的终端处于奇怪的状态我花了一段时间才最终将其调试到有问题的精确功能:tput smam
vs tput rmam
。
有没有办法检查当前的终端状态,希望一次性显示所有功能的当前值?
这将使我能够轻松区分工作终端和“损坏”终端,以找出修改的内容。
不过,找出任何特定功能的当前状态也是一个好的开始,例如smam
vs rmam
。
在 Ubuntu 19.10、Gnome 终端中测试。
答案1
这可能有效(VTE 实现了此控制的一部分):
请求 DEC 私有模式 (DECRQM)。对于 VT300 及更高版本,回复 DECRPM 为
犯罪现场调查?PS;下午$ y
其中 Ps 是 DECSET/DECSET 中的模式编号,Pm 是 ANSI DECRQM 中的模式值。
具体来说,PS是 7:
Ps = 7 ⇒ Auto-wrap Mode (DECAWM), VT100.
这对应于中使用的设置终端描述:
rmam=\E[?7l,
smam=\E[?7h,
所以...你会做
printf '\033[?7$p'
并期待回来
\033[?7;1$y
或者
\033[?7;2$y
分别取决于模式是否被设置或重置。
这还假设您的脚本/程序正在读取终端(不必要标准输入)。有几个测试/演示脚本在 xterm 的资源中,您可能会发现有用的阅读内容(尽管大多数资源不适用于 VTE)。一般来说我会测试这个功能测试,它已针对您使用的任何系统进行了打包。
答案2
到补充 托马斯·迪基的有用回答,它提供了符合 POSIX 标准的所有关键信息便利功能 tmode
,改编自有用的命令莫斯维的评论:
给定终端模式编号,它会打印'SET'
或'RESET'
来反映模式的状态;例如:
# Get status of the DECAWM (autowrap) mode
$ tmode 7
RESET
注意事项:
如果有人可以对这些内容有更多了解,请发表评论。
功能仅适用于肯定终端模拟器, 尤其不是在 Gnome 终端中:
- macOS:
iTerm2.app
,但不是内置的Terminal.app
- Ubuntu:
XTerm
和UXTerm
,但不是标准的 GnomeTerminal
- Windows(WSL):不是支持的;既不在旧控制台窗口中,也不在 Windows 终端中。
- macOS:
重新支持模式编号:
这console_codes(4) Linux
man
页面在部分“DEC 专用模式 (DECSET/DECRST) 序列”仅提及 1、3、5..9、25 和 1000在实践,上面提到的终端模拟返回以下有意义的值:
iTerm2.app
在 macOS 上:1..3、5..8、25、40..41、45、47、69、1000[U]XTerm
在 Ubuntu 上:1..7、9、12、18..19、25、30、35、38、40..42、44..45、47、66..67、69、80、95、1000
还有其他的,非数字的模式链接
man
页面中提到的,例如=
(DECPAM
) 和>
(DECPNM
) - 我不知道如何查询这些。尽管托马斯·迪基的链接DEC 私有模式转义序列的解释提到返回值
0
表示未知模式和3
/4
作为“永久设置/重置”;实际上,这似乎4
指示未知模式,已知模式仅报告1
(“设置”,即打开)或2
(“重置”,即关闭)。
外壳函数tmode
:
#! /bin/sh -
tmode() (
[ "$#" -eq 1 ] || { echo "Usage: tmode <mode-number>" >&2; return 2; }
modeNum="$1"
# Redirect stdin and stdout temporarily to the controlling terminal.
# This is necessary so that invocation such as `result=$(tmode 1)` work.
{
stty_settings="$(stty -g)"
stty -icanon -echo min 0 time 5
# Query the terminal.
printf '\33[?%s$p' "$modeNum"
result=$(dd count=1)
stty "$stty_settings"
} <> /dev/tty >&0 2> /dev/null
# Activate this to visiualize the raw result.
# printf %s "$result" | od -t x1 -t c > /dev/tty
# Print a friendly result.
case $result in
*';1$'*)
echo SET;;
*';2$'*)
echo RESET;;
# NOTE: It seems that 4 is only ever used to signal a nonexistent mode.
# *';3$'*)
# echo PERMANENTLY SET;;
# *';4$'*)
# echo PERMANENTLY RESET;;
*)
echo "Unknown mode: $modeNum" >&2;;
esac
)
答案3
设置模式
ESC [ Ⓝ h
ESC [ ? Ⓝ 小时
重置模式//取消设置
ESC [ Ⓝ l
ESC [ ? Ⓝ 升
请求模式 //查询状态
ESC [ Ⓝ $ p
ESC [ ? Ⓝ $p
Ⓝ 是十进制数(众数)
在外壳中测试
#set
echo -ne '\e[?1049h'
#query = set
echo -ne '\e[?1049$p'; cat
^[[?1049;1$y
#reset
echo -ne '\e[?1049l'
#query = not set
echo -ne '\e[?1049$p'; cat
^[[?1049;2$y
参考文献
xterm 文档:DECRQM DECRQM
https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#:~:text=DECRQM
注意:使用 chrome 访问可以滚动以突出显示网页中的关键字
控制序列
https://terminalguide.namepad.de/seq/
模式列表
https://terminalguide.namepad.de/mode/
设置模式
https://terminalguide.namepad.de/seq/csi_sh/
https://terminalguide.namepad.de/seq/csi_sh__p/
请求方式
https://terminalguide.namepad.de/seq/csi_sp_t_dollar/
https://terminalguide.namepad.de/seq/csi_sp__p_t_dollar/
vt100 文档
https://vt100.net/docs/vt510-rm/DECRQM.html
https://vt100.net/docs/vt510-rm/DECRPM.html
https://vt100.net/docs/vt220-rm/chapter4.html#S4.6