在 xterm 中读取当前文本颜色

问题描述 投票:0回答:4

我正在编写各种实用程序,而且我真的很喜欢彩色文本。没什么花哨的,只是使用转义序列。我创建了一个具有 pprint(msg, color) 函数的简单类。找到代码后,我已经很容易地工作了here

我遇到的问题是我应该能够在打印后关闭颜色。例如,假设用户运行我的程序,该程序以默认终端颜色打印几乎所有内容,但出现错误,我想以红色打印错误。我在错误消息前加上“[0;32m”前缀,并且该消息为红色。不幸的是,在我更改之前所有文本都是红色的。当我的程序运行时,这通常没问题,因为我知道消息应该是什么颜色。但是,在我的程序结束后,颜色仍然存在。基本上,我想在程序启动时读取当前颜色,并在完成时恢复它。与脚本退出时恢复密码的方式相同。

如何读取当前的转义序列?

系统: 红帽 5.x 重击 Python 2.3

感谢您的帮助。

python bash xterm
4个回答
152
投票

不要使用混淆的转义序列,而是使用

tput
设施。以下是我用于 PS1 提示的
~/.bashrc
的摘录:

BLACK=$(tput setaf 0)
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
LIME_YELLOW=$(tput setaf 190)
POWDER_BLUE=$(tput setaf 153)
BLUE=$(tput setaf 4)
MAGENTA=$(tput setaf 5)
CYAN=$(tput setaf 6)
WHITE=$(tput setaf 7)
BRIGHT=$(tput bold)
NORMAL=$(tput sgr0)
BLINK=$(tput blink)
REVERSE=$(tput smso)
UNDERLINE=$(tput smul)

要重置颜色信息,使后续文本采用正常的终端颜色,您可以将

${NORMAL}
添加到末尾,如下所示:

echo "${RED}this is red ${NORMAL}this is normal"


6
投票

事实上,这是可能的——因为 xterm,以及兼容终端。

例如,

xtermcontrol 使用

OSC 10
控制序列来检索 default 前景色/背景色。自 2002 年起,它就被记录在 xterm 中。

对于其他终端:

  • 在RHEL 5中,“终端”程序是gnome-terminal 2.16.0;该版本无法识别
    OSC 10
    (使用等效的 CentOS 5 进行测试)。
  • 这个问题是在 2010 年提出的,指的是 Red Hat enterprise 版本,如果有的话,它的更新速度比 Debian 慢。
  • 随着时间的推移,Debian 7(2012 年初)上的 gnome-terminal 3.4.1.1 也无法识别控制序列。
  • 最后,在 Debian 8 3.14.1(2014 年末)中,该功能得到了认可。
  • CentOS 7 的 gnome-terminal 3.14.3 可识别控制序列。

很好奇它是何时添加的,请记住 VTE 的开发人员不编写文档。所以...研究 git 日志显示

commit 1b8c6b1aac587b79476a60a5830385abc939430d 
Author: Egmont Koblinger <[email protected]> 
Date:   Wed Jan 22 00:13:51 2014 +0100

    emulation: Add support for OSC 1?1[017] (fg, bg, highlight colors)

    https://bugzilla.gnome.org/show_bug.cgi?id=567444

另一方面,默认颜色与当前颜色不同。自 1999 年的 patch #93 起,用户就可以使用 xterm 使用

DECRQSS
控制序列来执行此操作。也就是说,将终端置于原始模式并执行类似的操作

printf '\033P$m\033\\'

将让它回复填写有 SGR 参数的字符串。

如果使用 SGR 设置颜色,这些代码将成为回复的一部分,例如

\033P1$r0;33m\033\\

表示前景色编号 3(编码为

33
)。

您可以停在那里(因为您可以提取这些参数并稍后重用它们以将终端设置为相同的状态),但是然后可以使用

OSC 4
获取实际的 RGB 颜色。您可以使用颜色编号(来自 SGR 序列),并发送如下内容:

printf '\033]4;3;?\033\\'

所以用 xterm 肯定是可行的。在 xterm 的下一次更新中将有一个

DECRQSS
的演示/测试脚本。

对于其他项目,您需要更多时间:

  • xtermcontrol 的开发人员忽略了

    DECRQSS
    (它没有设置/获取 SGR 代码的功能)。

  • VTE 的开发人员复制 xterm 功能以响应错误报告; VTE 来源没有提到

    DECRQSS
    。它的 git 日志在 2009 年提到了
    OSC 4
    ,但实现并不完整(它只允许 set 一种颜色,而不是 get 颜色)。


4
投票

我不相信这是可能的,而且如果是的话,它也不太可能便携。您能做的最好的事情就是发送

sgr0
,将所有属性重置为默认值(而不是以前的属性)。在 xterms 上,
sgr0
Esc[m
。如果您想重置颜色而不影响其他属性,请发送
op
,在 xterms 上是
Esc[39;49m

这些代码不应该被硬编码。您应该使用 terminfo、termcap 或 [n]curses。


4
投票
RED = 31
GREEN = 32
ESCAPE = '%s[' % chr(27)
RESET = '%s0m' % ESCAPE
FORMAT = '1;%dm'

def colorize(text, color):
    return ESCAPE + (FORMAT % (color, )) + text + RESET

此函数将返回一个字符串,该字符串将打印彩色,之后终端会自动重置。

© www.soinside.com 2019 - 2024. All rights reserved.