在 Ubuntu 终端输出不同颜色、粗体、下划线或其他样式的字体

嗯。调试时总发现自己打印的调试信息太过普通、单调,于是乎......

Notice

要在终端实现字体的特殊样式,通常通过使用特殊的控制字符来实现,而不是通过某语言本身的功能来实现。

在大多数终端中,可以使用 ANSI 转义序列来设置字体的颜色。ANSI 转义序列是一系列以 ESC 开头的字符,用于控制文本终端的属性,包括颜色、格式和光标位置等。ANSI 转义序列以 \033[ 开头,后跟属性代码,以设置不同的终端属性。
请注意,不同的终端可能对 ANSI 转义序列的支持程度不同。大多数 Unix/Linux 终端和 Windows 上的一些控制台仿真器(如 ConEmu、Cygwin 和 Windows Terminal)都支持 ANSI 转义序列。

Color

包括前景色和背景色。前景色指的是字体本身的颜色,背景色指的是字体的背景颜色。

一些常见颜色:黑色、红色、绿色、黄色、蓝色、洋红色、青色、白色。

先来看一下效果:

#define

见名知意,不再赘述。

cpp 复制代码
#define ANSI_COLOR_RESET   "\x1b[0m"		// 重置

#define ANSI_COLOR_BLACK   "\033[30m"		// 前景色
#define ANSI_COLOR_RED     "\x1b[31m"
#define ANSI_COLOR_GREEN   "\x1b[32m"
#define ANSI_COLOR_YELLOW  "\x1b[33m"
#define ANSI_COLOR_BLUE    "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN    "\x1b[36m"
#define ANSI_COLOR_WHITE   "\033[37m"

#define ANSI_BG_BLACK       "\x1b[40m"		// 背景色
#define ANSI_BG_RED         "\x1b[41m"
#define ANSI_BG_GREEN       "\x1b[42m"
#define ANSI_BG_YELLOW      "\x1b[43m"
#define ANSI_BG_BLUE        "\x1b[44m"
#define ANSI_BG_MAGENTA     "\x1b[45m"
#define ANSI_BG_CYAN        "\x1b[46m"
#define ANSI_BG_WHITE       "\x1b[47m"

#define ANSI_COLOR_BRIGHT_BLACK   "\x1b[90m"		// 前景亮色
#define ANSI_COLOR_BRIGHT_RED     "\x1b[91m"
#define ANSI_COLOR_BRIGHT_GREEN   "\x1b[92m"
#define ANSI_COLOR_BRIGHT_YELLOW  "\x1b[93m"
#define ANSI_COLOR_BRIGHT_BLUE    "\x1b[94m"
#define ANSI_COLOR_BRIGHT_MAGENTA "\x1b[95m"
#define ANSI_COLOR_BRIGHT_CYAN    "\x1b[96m"
#define ANSI_COLOR_BRIGHT_WHITE   "\x1b[97m"

#define ANSI_BG_BRIGHT_BLACK       "\x1b[100m"		// 背景亮色
#define ANSI_BG_BRIGHT_RED         "\x1b[101m"
#define ANSI_BG_BRIGHT_GREEN       "\x1b[102m"
#define ANSI_BG_BRIGHT_YELLOW      "\x1b[103m"
#define ANSI_BG_BRIGHT_BLUE        "\x1b[104m"
#define ANSI_BG_BRIGHT_MAGENTA     "\x1b[105m"
#define ANSI_BG_BRIGHT_CYAN        "\x1b[106m"
#define ANSI_BG_BRIGHT_WHITE       "\x1b[107m"

Example

cpp 复制代码
#include <iostream>

// 有的宏定义没有用到,但懒得删掉了 ×_×

#define ANSI_COLOR_BLACK   "\033[30m"
#define ANSI_COLOR_RED     "\x1b[31m"
#define ANSI_COLOR_GREEN   "\x1b[32m"
#define ANSI_COLOR_YELLOW  "\x1b[33m"
#define ANSI_COLOR_BLUE    "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN    "\x1b[36m"
#define ANSI_COLOR_WHITE   "\033[37m"

#define ANSI_COLOR_RESET   "\x1b[0m"

#define ANSI_BG_BLACK       "\x1b[40m"
#define ANSI_BG_RED         "\x1b[41m"
#define ANSI_BG_GREEN       "\x1b[42m"
#define ANSI_BG_YELLOW      "\x1b[43m"
#define ANSI_BG_BLUE        "\x1b[44m"
#define ANSI_BG_MAGENTA     "\x1b[45m"
#define ANSI_BG_CYAN        "\x1b[46m"
#define ANSI_BG_WHITE       "\x1b[47m"

#define ANSI_COLOR_BRIGHT_RED     "\x1b[91m"
#define ANSI_COLOR_BRIGHT_GREEN   "\x1b[92m"
#define ANSI_COLOR_BRIGHT_YELLOW  "\x1b[93m"
#define ANSI_COLOR_BRIGHT_BLUE    "\x1b[94m"
#define ANSI_COLOR_BRIGHT_MAGENTA "\x1b[95m"
#define ANSI_COLOR_BRIGHT_CYAN    "\x1b[96m"
#define ANSI_COLOR_BRIGHT_WHITE   "\x1b[97m"

#define ANSI_BG_BRIGHT_BLACK      "\x1b[100m"

int main() {

    std::cout << "\033[31mThis text will be red. \033[0m" << std::endl;
    std::cout << "\x1b[33mThis text will be yellow. \033[0m" << std::endl;
    std::cout << ANSI_COLOR_RED << ANSI_BG_YELLOW << "Hello, world!" << ANSI_COLOR_RESET << std::endl;
    std::cout << ANSI_BG_GREEN << ANSI_BG_MAGENTA << "¡Hola, mundo!" << ANSI_COLOR_RESET << std::endl;
    std::cout << ANSI_BG_YELLOW << ANSI_BG_CYAN << "Hallo, welt!" << ANSI_COLOR_RESET << std::endl;
    std::cout << ANSI_COLOR_BRIGHT_BLUE << "Your future will be bright!" << ANSI_COLOR_RESET << std::endl;
    std::cout << ANSI_COLOR_BLUE << "Your future will be bright!" << ANSI_COLOR_RESET << std::endl;

    std::cout << ANSI_COLOR_WHITE << "This is white. " << ANSI_COLOR_RESET << std::endl;
    std::cout << ANSI_COLOR_BRIGHT_WHITE << "This is bright white. " << ANSI_COLOR_RESET << std::endl;

    std::cout << ANSI_COLOR_WHITE << ANSI_BG_BRIGHT_BLACK << "BrightBlack. " << ANSI_COLOR_RESET << std::endl;
    std::cout << ANSI_COLOR_WHITE << ANSI_BG_BLACK << "Black. " << ANSI_COLOR_RESET << std::endl;

    return 0;
}

outcome

实现效果如下:

ROS_INFO

那么如何使用 ROS_INFO 来输出彩色字体呢?

cpp 复制代码
	// 创建一个字符串流
    std::stringstream ss;
    
    // 向字符串流中添加需要的信息和 ANSI 转义序列
    ss << "\x1b[31m\x1b[43m" << "Hello, world!" << "\x1b[0m";
    
    // 使用 ROS_INFO 输出字符串流中的内容
    ROS_INFO("%s", ss.str().c_str());

以上代码来自 GPT。但保险起见,在向流中添加信息和转义序列时,尤其需要反复使用同一字符串流时,最好先执行以下操作:

cpp 复制代码
ss.str("");

Bold & Underline

#define

见名知意,不再赘述。

cpp 复制代码
#define ANSI_BOLD_ON        "\x1b[1m"
#define ANSI_BOLD_OFF       "\x1b[22m"

#define ANSI_UNDERLINE_ON   "\x1b[4m"
#define ANSI_UNDERLINE_OFF  "\x1b[24m"

#define ANSI_COLOR_RESET    "\x1b[0m"

Example

cpp 复制代码
#include <iostream>

// ANSI 转义序列,用于设置字体加粗和取消加粗
#define ANSI_BOLD_ON      "\x1b[1m"
#define ANSI_BOLD_OFF     "\x1b[22m"

// ANSI 转义序列,用于设置下划线和取消下划线
#define ANSI_UNDERLINE_ON   "\x1b[4m"
#define ANSI_UNDERLINE_OFF  "\x1b[24m"

// ANSI 转义序列,用于重置终端颜色
#define ANSI_COLOR_RESET    "\x1b[0m"

int main() {
    // 输出加粗文字
    std::cout << ANSI_BOLD_ON << "Bold Text" << ANSI_COLOR_RESET << std::endl;
    // 输出带下划线的文字
    std::cout << ANSI_UNDERLINE_ON << "Underlined Text" << ANSI_COLOR_RESET << std::endl;

    return 0;
}

outcome

实现效果如下:

ROS_INFO

同上。

Other styles

#define

见名知意,不再赘述。

cpp 复制代码
#define ANSI_BLINK_ON       "\x1b[5m"   // 开启闪烁
#define ANSI_BLINK_OFF      "\x1b[25m"  // 关闭闪烁

#define ANSI_REVERSE_ON     "\x1b[7m"   // 开启反显
#define ANSI_REVERSE_OFF    "\x1b[27m"  // 关闭反显

#define ANSI_HIDDEN_ON      "\x1b[8m"   // 开启隐藏
#define ANSI_HIDDEN_OFF     "\x1b[28m"  // 关闭隐藏

#define ANSI_STRIKETHROUGH  "\x1b[9m"   // 开启删除线
#define ANSI_STRIKETHROUGH  "\x1b[99m"  // 关闭删除线

#define ANSI_RESET          "\x1b[0m"

Example

cpp 复制代码
#include <iostream>

// ANSI 转义序列,用于设置终端效果
#define ANSI_BLINK_ON       "\x1b[5m"   // 开启闪烁
#define ANSI_BLINK_OFF      "\x1b[25m"  // 关闭闪烁
#define ANSI_REVERSE_ON     "\x1b[7m"   // 开启反显
#define ANSI_REVERSE_OFF    "\x1b[27m"  // 关闭反显
#define ANSI_HIDDEN_ON      "\x1b[8m"   // 开启隐藏
#define ANSI_HIDDEN_OFF     "\x1b[28m"  // 关闭隐藏
#define ANSI_STRIKETHROUGH  "\x1b[9m"   // 开启删除线

// ANSI 转义序列,用于重置终端效果
#define ANSI_RESET          "\x1b[0m"

int main() {
    // 闪烁效果
    std::cout << ANSI_BLINK_ON << "Blinking Text" << ANSI_RESET << std::endl;
    std::cout << ANSI_BLINK_OFF << "No Blinking Text" << ANSI_RESET << std::endl;

    // 反显效果
    std::cout << ANSI_REVERSE_ON << "Reversed Text" << ANSI_RESET << std::endl;
    std::cout << ANSI_REVERSE_OFF << "No Reversed Text" << ANSI_RESET << std::endl;

    // 隐藏效果
    std::cout << ANSI_HIDDEN_ON << "Hidden Text" << ANSI_RESET << std::endl;
    std::cout << ANSI_HIDDEN_OFF << "No Hidden Text" << ANSI_RESET << std::endl;

    // 删除线效果
    std::cout << ANSI_STRIKETHROUGH << "Strikethrough Text" << ANSI_RESET << std::endl;

    return 0;
}

outcome

实现效果如下:

ROS_INFO

cpp 复制代码
#include <ros/ros.h>
#include <sstream>

// 自定义的打印函数,用于在ROS_INFO中使用特定标记实现效果
void customInfo(const std::string& message) {
    std::cout << message << std::endl;
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "example_node");
    ros::NodeHandle nh;

    // 创建一个字符串流
    std::stringstream ss;
    // 向字符串流中添加需要的信息,并使用特定标记来表示效果
    ss << "[blink]Hello, world![/blink] ";
    ss << "[reverse]Reversed Text[/reverse] ";
    ss << "[hidden]Hidden Text[/hidden] ";
    ss << "[strikethrough]Strikethrough Text[/strikethrough]";
    // 使用自定义的打印函数打印信息
    customInfo(ss.str());

    ros::spin();
    return 0;
}

Combination

以上(并不互相冲突的)诸多效果可组合使用。略。

相关推荐
PyAIGCMaster2 小时前
ubuntu装P104
服务器·网络·ubuntu
赵大仁10 小时前
在 CentOS 7 上安装 Node.js 20 并升级 GCC、make 和 glibc
linux·运维·服务器·ide·ubuntu·centos·计算机基础
vvw&10 小时前
Docker Build 命令详解:在 Ubuntu 上构建 Docker 镜像教程
linux·运维·服务器·ubuntu·docker·容器·开源
shada12 小时前
Ubuntu 24.04 APT源配置详解
linux·ubuntu
vvw&12 小时前
如何在 Ubuntu 22.04 上安装和使用 Composer
linux·运维·服务器·前端·ubuntu·php·composer
奔跑草-13 小时前
【数据库】SQL应该如何针对数据倾斜问题进行优化
数据库·后端·sql·ubuntu
soragui14 小时前
【Ubuntu】如何轻松设置80和443端口的防火墙
linux·运维·ubuntu
worthsen14 小时前
ubuntu 网络管理--NetworkManager
ubuntu
Smile_Gently14 小时前
Ubuntu环境 nginx.conf详解(二)
运维·服务器·前端·nginx·ubuntu
vvw&19 小时前
如何在 Ubuntu 22.04 上安装 phpMyAdmin
linux·运维·服务器·mysql·ubuntu·php·phpmyadmin