在你的 shell 中使用 ANSI 转义码
五种 shell,五种把 ESC 字节送上 stdout 的语法 —— 并排呈现。Bash 与 Zsh 提供 ANSI-C 引用($'\e[…]')和 printf;Zsh 还增加了仅在 prompt 中生效的 %F{red} 快捷形式;Fish 完全不用转义字面量,而以 set_color 内建命令实现;PowerShell 7+ 内置 $PSStyle,但 5.1 仍需 [char]27;cmd.exe 依赖主机层的 ConPTY 支持,批处理本身没有干净的 ESC 写法。每个 shell 都附带可用片段、最常踩的那个坑,以及对应序列的链接。
在 Bash 中使用 ANSI 转义码
Bash 有三种可靠方式输出 ESC 字节:printf 配合八进制 / 十六进制转义(符合 POSIX,跨 dash / sh 最稳);ANSI-C 引用 $'\e[...]'(仅 bash + zsh,但可读性最佳);以及 tput(基于 terminfo,跨 $TERM 最稳)。请避免 echo -e —— 它在 bash 中可用但在 dash / sh 中不可用,在 Debian /bin/sh 下会静默失败。
常用写法
在任何 POSIX shell 中均可工作 —— bash、dash、ash、ksh、mksh、busybox sh。#!/bin/sh 脚本应使用此形式。
printf '\033[1;31m%s\033[0m %s\n' 'error:' 'permission denied'仅 bash 与 zsh —— 但可读性无可替代。\e 仅在 $'…' 中展开为 ESC 字节,普通 '…' 与 "…" 不展开。
red=$'\e[31m'
bold=$'\e[1m'
reset=$'\e[0m'
echo "${bold}${red}error:${reset} permission denied"tput 根据当前 $TERM 解析能力名,同一脚本可在 dumb / 16 色 / 256 色终端上正常降级。
RED=$(tput setaf 1)
BOLD=$(tput bold)
RESET=$(tput sgr0)
printf '%s%serror:%s permission denied\n' "$BOLD" "$RED" "$RESET"Bash 仅在传入 -e 时解释反斜杠转义。dash / POSIX 模式 sh 会把 -e 当作字面参数输出,转义不会展开;请用 printf 或 $'…' 代替。
# Works in bash …
echo -e '\033[31merror\033[0m'
# … breaks under dash / sh — outputs literal: -e \033[31merror\033[0m在 Zsh 中使用 ANSI 转义码
Zsh 继承了 bash 的 ANSI-C 引用($'\e[…]'),并增加了 prompt 展开快捷形式 —— %F{red}…%f 表示前景色、%B…%b 表示加粗、%K{blue}…%k 表示背景色 —— 仅在 $PS1 / $PROMPT / $RPROMPT 中或 print -P 之后展开。在 prompt 之外,请像 bash 一样使用:$'\e[31m' 或 printf '\033[31m…'。autoload colors 模块提供命名数组 $fg / $bg / $reset_color,可读性更好。
常用写法
%F{name}…%f / %B…%b / %K{name}…%k 仅在 prompt 内展开。仅当混合 zsh 无法计算宽度的原始 \e 码时,才需要 %{…%} 包裹。
# In ~/.zshrc
PS1='%B%F{green}%n@%m%f%b:%F{blue}%~%f%# '同样的 %F{red}…%f 简写,可在脚本任意位置着色,无需写出 SGR 字节。
print -P '%F{red}error:%f permission denied'需要完整 SGR 控制(truecolor、OSC 等)时 prompt 码无法覆盖 —— 改用字面转义。
local red=$'\e[38;2;255;120;120m'
local reset=$'\e[0m'
echo "${red}truecolor red${reset}"加载 $fg / $fg_bold / $bg / $reset_color 关联数组,让脚本以英文而非 SGR 数字呈现。
autoload -U colors && colors
echo "${fg[red]}error:${reset_color} permission denied"在 Fish 中使用 ANSI 转义码
Fish 不提供 $'…' 或 \e 展开 —— 单双引号都不解释反斜杠转义。原生方案是 set_color,一个接受颜色名(red、blue、brmagenta)或 24 位十六进制(cba6f7)的内建命令,并支持 --bold / --italic / --underline / --background 等参数。少数需要原始字节(OSC、DCS 等)的情况可用 printf '\e[…]'。
常用写法
直接管道发送颜色变更;用 set_color normal 重置。源码中无任何转义字面量。
set_color red
echo "error: permission denied"
set_color normal行内颜色切换需把 set_color 输出捕获到 echo 参数中。
echo (set_color red)"error:"(set_color normal)" permission denied"十六进制参数底层发送 SGR 38;2;R;G;B。与 --background 搭配可同时控制前景与背景。
set_color cba6f7 --bold
echo "lavender bold"
set_color normalset_color 未覆盖的字节(窗口标题、超链接、备用屏幕)请回退到 printf。
# Set window title via OSC 0
printf '\e]0;%s\a' "$argv[1]"在 PowerShell 中使用 ANSI 转义码
PowerShell 7.2+ 内置 $PSStyle —— 一个将每个 SGR 颜色与属性暴露为属性的对象($PSStyle.Foreground.Red、$PSStyle.Bold、$PSStyle.Reset)。底层发送 ANSI,并遵守 $PSStyle.OutputRendering 控制重定向时的输出。Windows PowerShell 5.1(仍随 Windows 10/11 一起发布)没有 $PSStyle;标准变通方案是用 [char]27 构造 ESC 字节,或在 PS 6+ 中使用 `e(反引号 e)双引号字符串。Write-Host -ForegroundColor 走的是主机 console API,不是 ANSI,因此不能与 $PSStyle 组合,重定向时会被剥离。
常用写法
现代语义化 API —— 自动重置、感知重定向、可组合。新代码请优先使用。
"$($PSStyle.Bold)$($PSStyle.Foreground.Red)error:$($PSStyle.Reset) permission denied"ESC 的十进制值是 27。先存入 $e,之后像普通字符串一样拼接转义序列。
$e = [char]27
"$e[1;31merror:$e[0m permission denied"反引号 e 是 PowerShell 的 ESC 转义 —— 不能用 $PSStyle 时最简洁的写法。
"`e[1;31merror:`e[0m permission denied"默认 Host 模式:终端输出 ANSI,重定向 / 管道输出剥离。设为 Ansi 强制输出,PlainText 完全禁用。
$PSStyle.OutputRendering = 'Ansi' # always emit, even when redirected
$PSStyle.OutputRendering = 'PlainText' # never emit
$PSStyle.OutputRendering = 'Host' # default: terminal yes, redirect no在 cmd.exe / 批处理中使用 ANSI 转义码
cmd.exe 自 Windows 10 build 14393(Anniversary Update,2016)起支持 ANSI,并在任何 ConPTY 感知的主机上默认启用 —— Windows Terminal、VS Code 终端、Cursor、Hyper。通过 Win+R cmd 打开的传统 conhost.exe 窗口是否启用 ANSI 取决于 Windows 版本及每窗口的 VT 处理标志。批处理本身没有干净的 ESC 字节语法:要么用能保存 0x1b 字节的编辑器把字面字符嵌入 .bat 文件,要么使用 for /f prompt $H 技巧。任何稍复杂的场景,建议从批处理里调用 PowerShell(powershell -NoProfile -Command "…")代替。
常用写法
黑魔法批处理写法 —— $H 是 prompt 的退格令牌,for /f 循环捕获单字节,经裁剪后作为 ESC 使用。源自 Microsoft 官方 ConPTY 示例。
@echo off
for /f %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
echo %ESC%[1;31merror:%ESC%[0m permission denied与 ANSI 无关但几乎总是配套使用:chcp 65001 让 cmd 以 UTF-8 解析脚本与输出(默认是 OEM 437 / 936 等)。
@echo off
chcp 65001 > nul
echo Multilingual: αβγ • 中文 • emoji 🚀需要多于一两行彩色输出时,调用 PowerShell 更短、更可读,并在每个 Windows 主机上行为一致。
@echo off
powershell -NoProfile -Command "Write-Host \"$([char]27)[1;31merror:$([char]27)[0m permission denied\""参见
/use 覆盖库层(chalk、fatih/color、rich、ncurses)。本页是 shell 语法层 —— 在 dotfile 里如何拼写一条转义。terminfo 把 tput 能力映射到这些 shell 最终发送的字节;pitfalls 收录所有「语法没问题但运行时仍然坏掉」的情况。