如何将彩色字符打印到支持彩色字符的Linux终端?

如何判断终端是否支持颜色码?


当前回答

在你输出任何你需要的颜色之前,确保你在一个终端:

[ -t 1 ] && echo 'Yes I am in a terminal'  # isatty(3) call in C

然后你需要检查终端能力,如果它支持颜色

在使用terminfo(基于Linux)的系统上,您可以获得支持的颜色数量为

Number_Of_colors_Supported=$(tput colors)

在使用termcap(基于BSD)的系统上,您可以获得支持的颜色数量为

Number_Of_colors_Supported=$(tput Co)

然后做出决定:

[ ${Number_Of_colors_Supported} -ge 8 ] && {
    echo 'You are fine and can print colors'
} || {
    echo 'Terminal does not support color'
}

顺便说一下,不要像之前建议的那样使用ESC字符着色。 使用标准的终端调用功能,将为您指定特定终端支持的正确颜色。

BSD Based
fg_black="$(tput AF 0)"
fg_red="$(tput AF 1)"
fg_green="$(tput AF 2)"
fg_yellow="$(tput AF 3)"
fg_blue="$(tput AF 4)"
fg_magenta="$(tput AF 5)"
fg_cyan="$(tput AF 6)"
fg_white="$(tput AF 7)"
reset="$(tput me)"
Linux Based
fg_black="$(tput setaf 0)"
fg_red="$(tput setaf 1)"
fg_green="$(tput setaf 2)"
fg_yellow="$(tput setaf 3)"
fg_blue="$(tput setaf 4)"
fg_magenta="$(tput setaf 5)"
fg_cyan="$(tput setaf 6)"
fg_white="$(tput setaf 7)"
reset="$(tput sgr0)"
Use As
echo -e "${fg_red}  Red  ${fg_green} Bull ${reset}"

其他回答

在OSX shell上,这为我工作(包括“红色文本”前面的2个空格):

$ printf "\e[033;31m  red text\n"
$ echo "$(tput setaf 1)  red text"

我知道这个问题很老了,但我把这个答案贴出来给未来的读者。我用c++写了一个用于彩色输出的库。这使用操纵者,使工作容易支持跨平台,但没有在这里测试是如何使用这个,

#include "srilakshmikanthanp/ANSI.hpp"

using namespace srilakshmikanthanp;

3位和4位颜色:

// background
std::cout << ansi::BGyellow;
// foreground
std::cout << ansi::FGblue;
// output
std::cout << "Blue on yellow";
// reset
std::cout << ansi::reset;

8位颜色:

// background
std::cout << ansi::BGcolor(157);
// foreground
std::cout << ansi::FGcolor(100);
// outpt
std::cout << "8 bit color";
// reset
std::cout << ansi::reset;

24位颜色:

// background
std::cout << ansi::BGcolor(0, 255, 0);
// foreground
std::cout << ansi::FGcolor(0, 0, 255);
// output
std::cout << "24 bit color";
// reset
std::cout << ansi::reset;

字符串:

使用ansi::str可以很容易地将这个操作符转换为字符串

std::string BGyellow = ansi::str(ansi::BGyellow);
std::string FGblue = ansi::str(ansi::FGblue);
std::string reset = ansi::str(ansi::reset);

std::cout << BGyelow;
// foreground
std::cout << FGblue;
// output
std::cout << "Blue on Yellow";
// reset
std::cout << reset;

你可以在github上找到更多的信息:)

你可以直接编写ANSI转义代码来控制颜色,也可以使用诸如{fmt}这样的库来提供api。

例如:

#include <fmt/color.h>

int main() { 
  fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
             "Hello, {}!\n", "world");
}

打印

大多数现代终端都支持ANSI转义序列,但您可以使用terminfo数据库进行检查。

您需要输出ANSI颜色代码。注意,并非所有终端都支持此功能;如果不支持颜色序列,就会显示垃圾。

例子:

 cout << "\033[1;31mbold red text\033[0m\n";

这里,\033是ESC字符,ASCII 27。它后面跟着[,然后是0个或多个用;隔开的数字,最后是字母m。这些数字描述了从这一点开始切换的颜色和格式。

前景色和背景色的代码如下:

         foreground background
black        30         40
red          31         41
green        32         42
yellow       33         43
blue         34         44
magenta      35         45
cyan         36         46
white        37         47

此外,你可以使用这些:

reset             0  (everything back to normal)
bold/bright       1  (often a brighter shade of the same colour)
underline         4
inverse           7  (swap foreground and background colours)
bold/bright off  21
underline off    24
inverse off      27

有关其他不太受广泛支持的代码,请参见维基百科上的表格。


要确定您的终端是否支持颜色序列,请读取TERM环境变量的值。它应该指定所使用的特定终端类型(例如vt100、gnome-terminal、xterm、screen……)。然后在terminfo数据库中查找;检查颜色能力。

我使用下面的解决方案,它非常简单和优雅,可以很容易地粘贴到源代码中,并在Linux/Bash上工作:

const std::string red("\033[0;31m");
const std::string green("\033[1;32m");
const std::string yellow("\033[1;33m");
const std::string cyan("\033[0;36m");
const std::string magenta("\033[0;35m");
const std::string reset("\033[0m");

std::cout << "Measured runtime: " << yellow << timer.count() << reset << std::endl;