bash 在 xterm 中读取当前文本颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4332478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:01:37  来源:igfitidea点击:

Read the current text color in a xterm

pythonbashxterm

提问by fandingo

I'm writing various utilities, and I'm really liking colorized text. Nothing fancy, just using escape sequences. I've created a simple class that has a pprint(msg, color) function. I've got it working rather easily after finding the codes here.

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

The problem that I'm having is that I should be able to turn off the color after printing. For example, let's say a user runs my program that prints almost everything in the default terminal color, but there is an error, and I want to print the error in red. I prefix my error message with '\033[0;32m', and the message is in red. Unfortunately, all text is red until I change it. That's generally fine while my program is running because I know what color the messages should be. However, the color remains after my program ends. Basically, I'd like to read the current color when my program starts, and restore it when finished. The same way that scripts restore the pwd when exiting.

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

How do I read the current escape sequence?

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

System: Red Hat 5.x Bash Python 2.3

系统:Red Hat 5.x Bash Python 2.3

Thanks for the help.

谢谢您的帮助。

采纳答案by Paused until further notice.

I don't believe that's possible and it's unlikely to be portableif it were. The best you can do is send sgr0which resets all attributes to default (not previous). On xterms, sgr0is Esc[m. If you want to reset the colors and not affect other attributes, send opwhich on xterms is Esc[39;49m.

我不相信这是可能的,如果是这样的话,它也不太可能是便携的。您能做的最好的事情是发送sgr0将所有属性重置为默认值(不是以前的)。在 xterms 上,sgr0Esc[m. 如果您想重置颜色而不影响其他属性,请op在 xterms 上发送which is Esc[39;49m

These codes should not be hardcoded. You should use terminfo, termcap or [n]curses.

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

回答by SiegeX

Rather than using obfuscated escape sequences, use the tputfacility instead. Here is an excerpt from my ~/.bashrcthat I use for my PS1 prompt:

与其使用混淆的转义序列,不如使用该tput工具。这是~/.bashrc我用于 PS1 提示的摘录:

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)

To reset the color information such that subsequent text is in the normal terminal color you would append ${NORMAL}to the end like so:

要重置颜色信息,以便后续文本使用正常的终端颜色,您可以${NORMAL}像这样附加到末尾:

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

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

回答by Torsten Marek

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

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

This function will return a string that will print colorized, with the terminal automatically being reset afterwards.

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

回答by Thomas Dickey

Actually, it's possible — for xterm, and compatibleterminals.

实际上,这是可能的 - 对于 xterm兼容终端。

xtermcontrolfor instance uses the OSC 10control sequence to retrieve the defaultforeground/background colors. It's been documented in xterm since 2002.

例如,xtermcontrol使用OSC 10控制序列来检索默认的前景色/背景色。自 2002 年以来,它已记录在 xterm 中。

For other terminals:

对于其他终端:

  • In RHEL 5, the "Terminal" program is gnome-terminal 2.16.0; that version does not recognize OSC 10(tested with the equivalent CentOS 5).
  • The question was asked in 2010, referring to the Red Hat enterpriseversion, which, if anything, is slower to update than Debian.
  • Moving forward in time, gnome-terminal 3.4.1.1 on Debian 7 (early 2012) also did not recognize the control sequence.
  • Finally, in Debian 8 with 3.14.1 (late 2014) the feature is recognized.
  • CentOS 7's gnome-terminal 3.14.3 recognizes the control sequence.
  • 在 RHEL 5 中,“终端”程序是 gnome-terminal 2.16.0;该版本无法识别OSC 10(使用等效的 CentOS 5 测试)。
  • 这个问题是在 2010 年提出的,指的是 Red Hat企业版,如果有的话,它的更新速度比 Debian 慢。
  • 随着时间的推移,Debian 7(2012 年初)上的 gnome-terminal 3.4.1.1 也无法识别控制序列。
  • 最后,在带有 3.14.1(2014 年末)的 Debian 8 中,该功能被识别。
  • CentOS 7 的 gnome-terminal 3.14.3 识别控制序列。

Curious when it was added, bear in mind that VTE's developers don't write documentation. So... studying the git log shows

好奇何时添加,请记住 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

On the other hand, the defaultcolors are not the same as the currentcolors. Users have been able to do this with xterm since patch #93 in 1999using the DECRQSScontrol sequence. That is, putting the terminal into raw mode and doing something like

另一方面,默认颜色与当前颜色不同。自1999 年补丁 #93以来,用户已经能够使用DECRQSS控制序列使用xterm 来做到这一点。也就是说,将终端置于原始模式并执行类似的操作

printf '3P$m3\'

would get it to reply with the string filled out with the SGR parameters.

会得到它用填充了 SGR 参数的字符串回复。

If colors were set using SGR, those codes would be part of the reply, e.g.

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

3P1$r0;33m3\

to denote foreground color number 3 (encoded as 33).

表示前景色编号 3(编码为33)。

You could stop there (because you could extract those parameters and reuse them to set the terminal to the same state later), but then getting the actual RGB colors would be possible using OSC 4. You'd use the color number (from the SGR sequence), and send something like this:

您可以停在那里(因为您可以提取这些参数并在以后重用它们以将终端设置为相同的状态),但随后可以使用OSC 4. 您将使用颜色编号(来自 SGR 序列),并发送如下内容:

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

So it's certainly doable with xterm. There'll be a demo/test-script for DECRQSSin the next update for xterm.

因此,使用 xterm 肯定是可行的。在DECRQSSxterm 的下一次更新中将有一个演示/测试脚本。

For other programs, you need more time:

对于其他程序,您需要更多时间:

  • xtermcontrol's developer overlooked DECRQSS(it has no feature for setting/getting SGR codes).

  • VTE's developers copy xterm features in response to bug reports; the VTE source does not mention DECRQSS. Its git log mentions OSC 4in 2009, but the implementation is incomplete (it only allows one to seta color, not getthe color).

  • xtermcontrol 的开发人员被忽略了DECRQSS(它没有设置/获取 SGR 代码的功能)。

  • VTE 的开发人员复制 xterm 功能以响应错误报告;VTE消息来源没有提到DECRQSS。它的 git logOSC 4在 2009 年有提到,但是实现不完整(它只允许设置颜色,而不是获取颜色)。