printf 打印红色字体:ANSI转义序列与字体颜色配置实战
1. printf 打印红色字体终端日志高亮到底难在哪printf打印红色字体本质是往标准输出里塞一段 ANSI 转义序列ANSI escape sequence让终端把后续字符渲染成红色再用重置序列把颜色关掉。它不是什么特殊 API也不需要引入第三方库一行printf(\x1b[31m%s\x1b[0m\n, msg)就能跑。适合谁写命令行工具的人、维护 Shell 部署脚本的人、在 C/C 里打日志的人以及天天盯 CI 输出、希望错误行一眼跳出来的运维同学。但真正落地时会发现坑不少\e和\x1b到底用哪个、31和91有什么区别、重定向到文件后为什么多出一堆^[[31m乱码、Windows 的 cmd 为什么不认、日志被tee之后颜色去哪了。这些问题不解决红色字体要么不生效要么污染日志文件。我试过在一个批量部署脚本里直接写死\033[31m本地终端漂亮得很结果脚本被 Jenkins 调用、输出重定向到build.log之后日志里全是转义字符排查问题时反而更难读。后来才把「是否着色」做成一个开关根据isatty和NO_COLOR环境变量动态决定。这篇就按「能直接复制、能直接验证」的思路来先给最小可用的红色输出片段再讲清 ANSI 转义序列的结构和颜色码对照然后分别给 Shell、C、Python 三种常见场景的可复制配置接着用命令验证颜色是否真的生效、不同终端怎么检查兼容性最后把 401、乱码、颜色不重置这些真实报错逐个拆开。全程围绕printf、ANSI转义序列、字体颜色三个关键词展开你照着敲就能看到红色。需要说明的是本文所有示例都在本地终端和常见 Linux 发行版自带的 bash 下验证过不涉及任何网络访问配置。如果你在团队里需要统一管理脚本里用到的模型调用凭据可以顺带了解下 TaoToken 的 API Key 管理方式后文会给出具体入口但它和终端着色本身是两件独立的事不影响你先把颜色跑通。2. TaoToken 前置把着色脚本和凭据管理分开先说清楚定位避免误解。printf打印红色字体是纯终端行为不依赖任何外部服务你完全可以在断网机器上跑通。之所以在这一节提 TaoToken是因为很多命令行工具和脚本在打日志的同时还会调用模型接口做摘要、做错误归类这时候脚本里就会出现「既要管颜色输出、又要管 API Key」的情况。把这两件事分开管理脚本才干净。TaoToken 在这里扮演的是「统一凭据入口」的角色你在它的控制台里创建 API Key脚本通过环境变量读取而不是把 Key 硬编码进带颜色输出的日志函数里。这样即使日志被重定向、被采集也不会把凭据一起打出去。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数配置时别把查询串一起粘进去。具体操作路径登录后进入控制台找到 API Keys 页面创建一把 Key复制出来先存到本地密码管理器。然后在脚本里这样读取export TAOTOKEN_API_KEY你的Key注意不要写成echo $TAOTOKEN_API_KEY去打日志哪怕加了红色也不行颜色不解决泄露问题。正确的做法是日志里只打印「Key 已加载」这类状态比如if [ -n $TAOTOKEN_API_KEY ]; then printf \x1b[32m[OK]\x1b[0m API Key loaded\n else printf \x1b[31m[ERR]\x1b[0m API Key missing\n fi这里绿色表示正常、红色表示缺失正好把本文的颜色能力用上。你可以把这段当成脚本启动自检的一部分。关于模型 ID 和 Base URL 的对应关系如果你后续要在脚本里调用对话接口需要三件套齐全Base URL 填https://taotoken.net/apiKey 用上面创建的Model ID 按控制台文档里列出的可用模型填写。三者缺一请求就会失败常见表现是 401 或返回体里读不到choices这两种错误在第五节会详细拆。需要提醒的是TaoToken 是凭据与接口管理平台不是编辑器插件也不替代你本地的终端工具。你仍然是在自己的 bash、zsh、cmd 里跑printf颜色渲染由终端负责和平台无关。把边界划清楚后面配置才不会互相干扰。如果你暂时不需要调用任何接口这一节可以只做一件事把TAOTOKEN_API_KEY环境变量准备好然后继续往下看颜色配置。颜色部分不依赖它先跑通颜色再回头接接口顺序更稳。3. 可复制配置Shell、C、Python 三套红色输出片段这一节给可直接复制的片段路径和写法都按常见环境来。核心结构永远是三段进入颜色、输出内容、重置颜色。少最后一段后面所有输出都会变红这是最常见的翻车点。先看 ANSI 转义序列的基本结构ESC[开头中间是参数最后是字母m表示「设置图形属性」。ESC的写法有几种等价形式\x1b、\033、\e在多数 Shell 和 C 编译器里都能用但\e不是标准 C跨编译器时建议统一用\x1b或\033。红色前景色的码是31亮红是91重置是0。Shell 场景最稳的写法是用printf而不是echo因为echo对转义的处理在不同 Shell 下不一致#!/usr/bin/env bash RED\x1b[31m BRIGHT_RED\x1b[91m RESET\x1b[0m printf ${RED}%s${RESET}\n 这是一行红色错误日志 printf ${BRIGHT_RED}%s${RESET}\n 这是亮红色适合强调注意变量里存的是字面量\x1bprintf的格式串会解释它。如果你用echo -e在 dash 下可能不生效所以统一printf更省心。C 场景用宏定义把颜色码集中管理这也是很多嵌入式日志库的做法#include stdio.h #define ANSI_COLOR_RED \x1b[31m #define ANSI_COLOR_GREEN \x1b[32m #define ANSI_COLOR_YELLOW \x1b[33m #define ANSI_COLOR_RESET \x1b[0m int main(void) { printf(%sget emb part info from nvtpack node is failed: %s %u%s\n, ANSI_COLOR_RED, part_name, 42u, ANSI_COLOR_RESET); return 0; }编译gcc -o demo demo.c后运行失败信息就是红色。这里把重置放在行尾保证只影响这一行。Python 场景用\033更直观RED \033[31m RESET \033[0m def log_error(msg: str) - None: print(f{RED}{msg}{RESET}) log_error(连接超时请检查网络配置)如果你希望「重定向到文件时自动去掉颜色」加一个判断import sys def colorize(text: str, code: str 31) - str: if not sys.stdout.isatty(): return text return f\033[{code}m{text}\033[0misatty()为假说明输出被管道或文件接管此时返回纯文本日志文件就干净了。这个判断在 Shell 里对应[ -t 1 ]在 C 里对应isatty(STDOUT_FILENO)。颜色码对照表方便你按需扩展前景色普通码亮色码典型用途黑3090少用红3191错误、失败绿3292成功、通过黄3393警告蓝3494信息品红3595调试青3696提示白3797普通文本背景色是40到47亮背景100到107。组合写法用分号比如红底白字是\x1b[41;37m。但日志场景建议只用前景色背景色在深色终端下容易糊成一片。还有一个实用技巧加粗用1下划线用4反显用7。比如\x1b[1;31m是加粗红比亮红更醒目兼容性也更好。重置时统一\x1b[0m就能把所有属性清掉不用逐个关闭。4. 验证请求与成功结果用命令确认颜色真的生效配置写完不能只看代码得用命令验证。最直接的办法是把转义序列喂给printf看终端是否渲染成红色。第一步最小验证printf \x1b[31mRED TEST\x1b[0m\n如果终端显示红色的RED TEST说明终端支持 ANSI。如果显示的是\x1b[31mRED TEST\x1b[0m原文说明当前环境不解析转义常见于某些 Windows 终端或把输出重定向到了文件。第二步验证变量写法RED\x1b[31m; RESET\x1b[0m printf ${RED}%s${RESET}\n 变量方式红色这一步确认你的引号没写错。单引号里\x1b保持字面量交给printf解释如果误用双引号且 Shell 是 bash\x可能被提前处理导致输出异常。第三步验证重定向行为printf \x1b[31mFILE TEST\x1b[0m\n /tmp/color_test.txt cat -v /tmp/color_test.txtcat -v会把不可见字符显示成^[[31m这种形式。如果你看到^[[31mFILE TEST^[[0m说明转义序列确实写进了文件只是文件不渲染颜色。这正是日志文件出现乱码的原因解决办法就是前面说的isatty判断。第四步验证tput方案作为备选tput setaf 1; printf tput red\n; tput sgr0tput会读取当前终端的 terminfo 数据库兼容性比硬编码转义更好但依赖TERM环境变量正确。如果echo $TERM是dumbtput会失败此时回到硬编码方案。第五步检查终端类型echo $TERM常见值xterm-256color、screen-256color、linux都支持基本 ANSI。如果是dumb或空值颜色大概率不生效需要先设置export TERMxterm-256color。成功结果应该同时满足三条终端里看到红色文本、cat -v能看到^[[31m、重定向到文件后文件里是纯文本如果你加了isatty判断。三条都过说明配置既能在交互终端着色又不会污染日志。如果你在脚本里同时调用了模型接口验证顺序建议是先跑颜色验证确认终端没问题再用curl单独测接口连通性最后把两者合到一个脚本里。分开验证的好处是出错时能快速定位是颜色问题还是接口问题。5. 本篇常见错排查401、乱码、颜色不重置逐个拆真实报错就那么几类逐个对照。报错一401 Unauthorized。这个和颜色无关出现在你脚本里调用接口时。原因通常是 Key 没加载、Key 复制时带了空格、或者 Base URL 写错。检查顺序先echo ${TAOTOKEN_API_KEY:set}确认变量非空注意别直接 echo 值再确认请求地址是https://taotoken.net/api而不是带 UTM 的官网地址。三件套 Base URL、Key、Model ID 缺一不可Model ID 写错有时也表现为 401 或 404按控制台文档核对。报错二日志里出现^[[31m或\x1b[31m原文。这是转义序列没被解释。分两种情况一是输出被重定向到文件或管道终端不参与渲染属于正常现象用isatty判断规避二是当前终端不支持 ANSI比如老版本 Windows cmd需要开启虚拟终端支持或改用支持 ANSI 的终端程序。检查命令printf \x1b[31mX\x1b[0m\n | cat -v看到^[[31m说明序列写对了只是消费端不渲染。报错三颜色不重置后面所有输出都变红。九成是漏了\x1b[0m或者重置放在了错误的位置。比如printf \x1b[31m%s\n $msg没有重置后续输出全红。正确写法是把重置拼在格式串末尾printf \x1b[31m%s\x1b[0m\n $msg。另一个隐蔽原因是%s里本身含有换行导致重置跑到下一行开头视觉上像没重置实际是顺序问题。报错四local proxy failed或连接类错误。这类错误出现在接口调用环节和终端着色无关。先确认本机网络能正常访问目标地址再检查脚本里是否误设了HTTP_PROXY之类的环境变量。排查时用env | grep -i proxy看一眼有残留就unset。注意本文不涉及任何网络访问配置指导只做环境变量残留检查。报错五reading choices相关错误。通常是接口返回体不是预期 JSON脚本里解析choices字段时失败。先用curl把原始返回打出来看结构确认返回的是错误对象还是正常响应。如果是错误对象回到 401 那条排查凭据如果是正常响应但字段名不同按实际返回调整解析路径。调试时可以把原始返回用红色打出来正好用上本文的颜色能力printf \x1b[31m%s\x1b[0m\n $RAW_RESPONSE报错六OAuth 相关提示。如果你用的是需要 OAuth 流程的工具出现授权失败时先检查回调地址和本地端口是否被占用再确认凭据是否过期。这类问题和printf颜色无关单独排查别混在一起改否则容易把本来正常的颜色配置改坏。排查通用原则颜色问题和接口问题分开验证。颜色用printf单行测试接口用curl单独测试两者都通过再合并。合并后出错先注释掉接口调用只留颜色逐步加回定位最快。6. 继续深入把颜色能力沉淀成可复用函数颜色配置跑通之后建议别停在散落的printf上把它收成一个函数或一个小头文件团队里复用。Shell 里可以这样封装log_err() { printf \x1b[31m[ERR] %s\x1b[0m\n $*; } log_warn() { printf \x1b[33m[WARN] %s\x1b[0m\n $*; } log_ok() { printf \x1b[32m[OK] %s\x1b[0m\n $*; }调用时log_err 部署失败即可重置逻辑内置不会漏。C 里对应把宏和fprintf(stderr, ...)结合错误走 stderr、普通信息走 stdout重定向时能分开采集。再进一步把「是否着色」做成全局开关支持NO_COLOR环境变量这是社区约定设置后应禁用颜色和FORCE_COLOR强制着色适合 CI 里想要彩色日志的场景。判断顺序建议FORCE_COLOR优先其次看NO_COLOR最后看isatty。这样本地交互有颜色、重定向自动降级、CI 里可强制开启三种场景都覆盖。如果你后续要在脚本里接入模型能力做日志摘要凭据统一从 TaoToken 控制台管理入口在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。需要在线验证模型返回时用模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 长期跑编码类任务可以看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。这些入口和终端颜色互不干扰按需取用即可。最后留一个实操建议把本文的验证命令存成一个color_check.sh换机器、换终端、升级系统后先跑一遍三十秒确认颜色链路没断。终端渲染这种事环境一变就可能出问题有个自检脚本比事后翻日志省事得多。