ansi转义序列可直接实现终端彩色输出,echo需-e参数解析转义符,ls需--color启用,tput更兼容多终端,ps1中非打印颜色码须用[ ]包裹,末尾重置码不可省略。

直接用 ANSI 转义序列就能让终端输出带颜色的文本,不需要装额外工具、不依赖特定语言,只要终端支持(绝大多数现代终端都支持),echo、printf、ls、grep 甚至 C/C++ 的 printf 都能生效。
为什么 echo 加颜色要带 -e 参数
因为 ANSI 转义序列本质是带特殊含义的字符串(比如 \033[31m),而默认情况下 echo 把反斜杠当普通字符处理,不会解析。加 -e 才会启用转义符解释:
-
echo "\033[31mred\033[0m"→ 原样输出那串字符,没颜色 -
echo -e "\033[31mred\033[0m"→ 正确渲染为红色文字 - 等价写法:
echo -e "\e[31mred\e[0m"(\e是\033的简写)
ls 彩色输出不生效的常见原因
不是命令本身问题,而是环境或配置没到位:
-
ls默认不开启颜色,必须显式启用:ls --color=auto或ls --color=always - 多数发行版通过 alias 自动启用,检查是否被覆盖:
alias ls—— 如果输出里没有--color,就说明 alias 没配 -
LS_COLORS环境变量为空或损坏会导致颜色失效,可用dircolors -p | head -5快速验证是否加载了默认规则 - 终端类型太旧(如
TERM=dumb)会禁用颜色,运行echo $TERM确认值是xterm-256color或类似支持 ANSI 的类型
用 tput 输出颜色更安全的场景
当你写 Shell 脚本、需要适配不同终端(比如 tmux、screen、某些 SSH 客户端)时,硬写 \033[... 可能出错,tput 会查 terminfo 数据库动态生成兼容序列:
-
RED=$(tput setaf 1)→ 获取当前终端下“红色前景”的正确序列 -
RESET=$(tput sgr0)→ 获取重置样式序列(比硬写\033[0m更可靠) - 组合使用:
echo "${RED}error${RESET}: file not found" - 注意:
tput在非交互式环境(如 cron 脚本)中可能失败,因为没分配终端,需加判断:if [ -t 1 ]; then ... fi
自定义 PS1 提示符时容易漏掉的括号
给 Bash 提示符加颜色,必须用 \[ 和 \] 包住所有非打印字符(即颜色代码),否则光标定位会错乱、换行异常:
- 错误写法:
PS1="\033[1;32m\u@\h:\w\$ \033[0m"→ 终端计算字符串长度时把颜色码也算进去,导致编辑长命令时光标跳位 - 正确写法:
PS1="\[\033[1;32m\]\u@\h:\w\[\033[0m\]\$ "→\[和\]告诉 bash 这段不占显示宽度 - 如果用了
tput,也要包住:PS1="\[$(tput setaf 2)\]\u@\h:\w\[$(tput sgr0)\]\$ "
最常被忽略的是:颜色序列末尾的 \033[0m(或 tput sgr0)不是可选的——漏掉它会让后续所有输出持续带样式,包括你执行的命令结果、其他程序的输出,甚至影响 vim 等全屏程序的显示逻辑。











