如何确定控制台输出的当前颜色?


14

我知道,如果有彩色终端可用,则可以使用转义字符为其输出着色

但是是否有可能找出当前输出显示为哪种颜色?或者,如果我现在将其输出,文本将是什么颜色?

我要求在使用这些转义字符时不要破坏任何以前的颜色设置。“默认前景色”转义字符是从配色方案中获取的信息,而不是在更改之前的文本颜色。


查看termcap和terminfo变量,似乎是不可能的。例如,你可以得到的颜色数,你的终端支持与echotc Coechoti colors,而只是有没有变量,它存储当前颜色代码的定义。
jimmij 2014年

@jimmij我是这么想的,并希望我错过了一些东西。如果您对不可能的事情有足够的把握,请回答,如果没有其他事情,我将最终接受。谢谢你的时间。
Minix

Answers:


11

通常,获得当前颜色是不可能的。终端的控制序列处理发生在终端“内部”,无论发生在何处。使用终端模拟器(例如xterm或内置于提供内核虚拟终端的操作系统内核中的终端模拟器),模拟器的内部状态(包括其当前“图形再现”的概念(即颜色和属性))就在机器上本身,理论上是可以访问的。但是对于真正的终端,此信息位于通过串行链接连接的物理上独立的计算机上的某些RAM位置。

也就是说,某些终端包括一种机制,用于读取通过该串行链路发送的此类信息作为其终端协议的一部分。它们提供程序可以发送给终端的控制序列,从而使程序将有关其内部状态的信息作为终端输入发送回去mikeserv向您显示了xterm终端仿真器响应的控制序列。但是这些是特定于的xterm。例如,Linux内核和各种BSD内核中的内置终端仿真器是不同的终端类型,根本不实现任何此类控制序列。真实终端的整个系列也是如此。

DEC VT525终端实现了一种读出机制,但是具有一组与所使用的控制序列无关的控制序列xterm。一个发送DECRQSS(请求选择或设置)序列以请求当前图形再现,然后终端通过发送DECRPSS(报告选择或设置)进行响应。特别:

  1. 主机发送:DCS $ q mST(以SGR的控制功能部分为设置的DECRQSS)
  2. 终端响应:DCS 0 $ r 0 ; 3 3 ; 4 4 mST(具有SGR控制序列的参数和控制功能部分的DECRPSS,用于设置当前的前景色和背景色)

当然,仔细阅读您的问题后,您会发现您再次在那些欧洲货币体系中挥舞着覆有巧克力的香蕉。您实际上已尝试做的事情(已为此选择了一个解决方案,然后询问如何做该解决方案的一部分)是在编写一些彩色输出时保留了先前的状态。不仅有执行此操作的DEC VT控制序列,还有一个SCO控制台终端序列,可被xterm各种内核内置终端仿真器识别,还有一个termcap / terminfo条目,告诉您终端的含义。

termcap条目为scrc。terminfo条目为save_cursorrestore_cursor。这些名称在效果上会产生误导(尽管它们确实是在警告您所依赖的是事实而非法律上的东西)。实际的DECSC,DECRC,SCOSC和SCORC控制序列也可以保存和恢复当前图形格式。

鉴于您所指向的文章都是关于从shell脚本生成控制序列的,因此现在要查找的命令是tput

进一步阅读


好答案。很高兴我回去了。非常感谢。
Minix

@Minix-除了sc和之外rc,如果您的终端支持备用缓冲区,您可能还需要查看备用缓冲区。是的,这是一个很好的答案。Minix,也许还可以看一下:如何从用户空间使用/ dev / fb0作为控制台nosh他推荐的套房有自己的。
mikeserv

@mikeserv我看一下,谢谢您的链接:)
Minix

2
注意此“与xterm所使用的没有任何关系”-但是,xterm支持DECRQSS已有相当长的一段时间了。具有SGR响应的部分(包括颜色)可以追溯到1996
。– Thomas Dickey

2
请参阅xterm的控制序列文档中的进一步阅读,其中指出当xterm开始提供颜色DECRQSS(大约7年的延迟...)时,VT520 / etc文档不可用。
托马斯·迪基

10

在中,xterm您可以通过将颜色更改转义符更改为查询来获取报告的当前颜色RGB颜色代码。使用ESC ] Ps m-,但添加一个?问号。从文档

  • 如果"?"给出a而不是名称或RGB规范,xterm则以相同形式的控制序列进行答复,该序列可用于设置相应的动态颜色。因为可以在一个控制序列中给出一对以上的颜色编号和规格,xterm所以可以做出多个答复。
    • P s = 1 0→将VT100文本前景色更改为P t。
    • P s = 1 1→将VT100文本背景颜色更改为P t。
    • P s = 1 2→将文本光标的颜色更改为P t。
    • P s = 1 3→将鼠标前景色更改为P t。
    • P s = 1 4→将鼠标背景色更改为P t。
    • P s = 1 5→将Tektronix前景色更改为P t。
    • P s = 1 6→将Tektronix背景色更改为P t。
    • P s = 1 7→将突出显示的背景色更改为P t。
    • P s = 1 8→将Tektronix光标颜色更改为P t。
    • P s = 1 9→将突出显示的前景色更改为P t。

我非常怀疑这是否可能在另一个终端仿真器中工作,但是xterm如果您运行...

printf '\033]11;?\007'

... xterm将按如下顺序将其推回到终端的输入缓冲区中...

11;rgb:ffff/ffff/ffff

...对于背景还是前景:

printf '\033]10;?\007'

10;rgb:0000/0000/0000

因此,当我运行时printf '\033]10;rgb:8f8f/8f8f/8f8f8f\007,终端中以前“正常”的所有文本都变成了浅蓝色。随后,运行printf '\033]10;rgb:bfbfbf/bfbfbf/bfbfbf\007'将所有浅蓝色文本恢复为“正常”。如何使用此值仅更改前进文本的颜色?
fourpastmidnight

@fourpastmidnight:也许是clear第一个?
mikeserv

我以为我不了解文档。它确实明确地说“ P s = 1 0->更改VT100前景色”,这就是它的作用。;)但这不是我所期望的。我可能需要使用从“ P s = 1 0; Pt =?”中检索的RGB值。与另一个转义的命令来实现我想要的。
fourpastmidnight

好的,因此向printf '\033]10;?\007'xterm查询终端的当前前景色。如果您的终端以“ normal”(例如7作为前景色)启动,但是tput setaf 3在运行该printf命令之前运行,则printf上面的命令仍会返回“ normal”-没错,因为这是终端的当前前景色。我所希望的是一种检索当前光标位置的当前颜色的方法,这样我就可以将其保存下来以供以后“还原”(按照OP)。
fourpastmidnight

1
@fourpastmidnight-您是否遵循此处答案中的链接?同样,托马斯·迪基 Thomas Dickey)- (他对这个问题的另一个答案进行了评论)xterm的维护者,并且是这里的活跃成员。(链接指向他的网站- xterm的逸出文档非常广泛-基本上是任何其他想要编写终端的程序员的标准参考)
mikeserv
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.