Linux终端提示符定制指南:从PS1原理到动态配置

发布时间:2026/9/7 16:00:00
Linux终端提示符定制指南:从PS1原理到动态配置 1. 为什么一个整天盯着看的提示符值得你花时间折腾先问个问题你每天在终端里敲多少条命令几十条算少的上百条很正常。每一次敲回车之前你的眼睛都会扫一眼提示符——那个userhostname:~$。如果你从来没觉得它碍眼那恭喜你说明你还没到被它折磨的阶段。但等你开始管理多台服务器、在本地和远程之间来回切换、频繁出入不同目录的时候你会发现自己陷入了一种我是谁、我在哪、我在干什么的哲学困惑。尤其是在Ubuntu默认终端里userubuntu:~$这串字符长得又长又没区分度一旦你同时开着五六个终端窗口真的会切错机器、删错目录、跑错环境。这不是危言耸听我身边就有同事因为提示符里看不出当前在哪个虚拟环境直接把生产环境的依赖给覆盖了。修改终端提示符本质上就是在PS1这个环境变量上做文章。它决定了你终端里每一行命令前面显示什么信息、用什么颜色、如何布局。这个东西虽然看着只是颜值问题但往深了说它直接影响你的操作效率、误操作率甚至影响你每天敲命令的心情。这篇文章不准备给你堆一堆网上一搜一大把的复制这段代码就行的零散命令而是从底层原理讲起把PS1变量的结构、转义序列、颜色机制、以及各种改完为啥没生效颜色为啥是乱的git分支怎么显示不出来的坑全部梳理一遍。最后我还会分享一些我自己在实战中打磨出来的配置方案包括函数嵌套、动态提示符、左右分栏布局这些进阶玩法。你把这篇文章读透基本就能自如地定制出一套完全属于你自己的终端提示符而不是永远停留在复制别人的配置然后用不习惯的水平。2. 动手之前的准备工作看清你当前的提示符到底是什么在改任何东西之前我先教你一个最基础的排查手段这是所有后续操作的地基。别嫌我啰嗦我发现很多人改提示符改到一半发现诶我怎么改了没动静大多数都是因为根本没搞清楚当前环境用的到底是哪种机制。2.1 你的shell到底是什么首先确认你当前用的shell。Ubuntu里默认是bash但你如果用zsh、fish之类的改法完全不同。简单点在终端里执行echo $SHELL如果输出/bin/bash那下面的内容都可以直接照搬如果是/usr/bin/zsh那你需要去看.zshrc而不是.bashrc如果是fish那配置方式又是另一套逻辑了。我见过太多人照着bash的教程去改zsh的配置改完发现全没用最后还把.zshrc搞坏了。先确认环境能省下大半天的折腾时间。2.2 查看你当前PS1的值PS1是bash里控制一级提示符就是你正常敲命令时看到的那一行的环境变量。查看它现在的值echo $PS1在绝大多数Ubuntu系统上默认值大概是这样的\[\e]0;\u\h: \w\a\]${debian_chroot:($debian_chroot)}\u\h:\w\$看到这一串乱码先别慌它其实拆解开来也没那么神秘。\u是当前用户名\h是主机名不是完整的域名是短主机名\w是当前工作目录的完整路径\$是超级用户时显示#否则显示$。至于开头那段\[\e]0;\u\h: \w\a\]它是在给终端窗口设置标题不显示在命令行前面的提示符中只在终端窗口的标题栏里生效。还有一种情况你的Ubuntu可能是默认开箱的状态echo $PS1显示的就很简单比如${debian_chroot:($debian_chroot)}\u\h:\w\$这都正常。把当前值弄清楚之后你才能知道修改之后变没变、变了多少。2.3 区分临时生效和永久生效我个人的习惯是先改临时生效的部分试试效果确认满意了再写进配置文件里。如果你一上来就改配置文件万一写错了每次打开终端都会报错甚至可能直接没法正常打开bash被迫进入恢复模式去修复那个过程真的非常折磨。临时修改就是直接给PS1变量赋值export PS1hello 执行完你就发现提示符变成了hello 这证明变量生效了改这个能直接改变显示。但如果你此时新开一个终端窗口会发现提示符又变回原来的样子了——这是因为临时修改只在当前shell进程里生效没有保存到配置文件里。确认满意之后再把它写进~/.bashrc末尾新开终端才能永久生效。注意export不是必须的PS1本来就会被子shell继承但加上它更稳妥也不会出什么幺蛾子。2.4 每次修改完必须做的事改完~/.bashrc之后大多数人会告诉你重新打开终端就行了但更高效的方法是执行source ~/.bashrc这个命令会重新加载配置文件让当前终端立刻应用新配置不需要关掉窗口再开一个。这里有个小坑如果你在~/.bashrc里配置了把PS1写入到某种只在登录shell里执行的代码块中source之后可能看到的效果和你重新开终端不完全一样。所以我的习惯是两边都验证一下——先source看有无报错再新开一个终端确认显示正常。两条路都通了这事才算真的成了。3. PS1变量的底层拆解转义序列与转义技巧现在进入了这篇文章最核心的部分。你别嫌绕搞明白了这里后面所有花哨的玩法都是信手拈来搞不明白你就永远只能做复制-粘贴-碰运气的配置员。3.1 最常用的转义序列表PS1里的内容由两部分组成普通字符原样显示和转义序列以反斜杠开头会被bash解析成对应信息。下面这张表是我实践中最常用的你可以直接保存转义序列含义示例输出\u当前用户名root 或 yourname\h主机名短ubuntu\H完整主机名含域名ubuntu.example.com\w当前工作目录完整路径/home/user/project\W当前工作目录基名只取最后一级project\d日期格式为星期 月 日Mon Jan 15\t24小时制时间HH:MM:SS14:33:05\T12小时制时间02:33:05 PM\12小时制时间am/pm02:33 PM\#当前命令序号每次shell启动后自增1, 2, 3...\!当前shell历史命令编号1024\$普通用户为$root为#$\n换行换行\\反斜杠本身\\[开始一个非打印字符序列不显示\]结束非打印字符序列不显示这里我有必要单独强调\[和\]这两个不起眼的东西。它们之所以重要是因为终端在计算提示符的实际显示宽度时会把颜色控制码等非打印字符也算进去。如果你不用\[和\]把颜色代码包起来bash计算出来的行宽就是错的结果就是你敲一条长命令输到快靠近右边缘的时候终端不会正确换行文字会直接重叠、覆盖、甚至乱跳。这个坑我踩了不止一次每次都是配完颜色之后发现长命令显示错乱排查半天才发现是漏了\[和\]。3.2 实操先改一个最简单但立刻能看出效果的开胃菜我们先做一个小改动让你感知一下我自己能控制提示符这件事。在终端里输入export PS1\u\h:\w\$ 这个效果和Ubuntu默认的差不多但如果你改成export PS1[\u\h] [\w]\n$ 你会发现提示符变成了两行上面一行是[用户名主机] [路径]下面一行只有一个$。这样做的最大好处是如果你的目录路径特别长提示符不会把整行都占满你敲命令的空间会大很多。这是很多人喜欢用两行提示符的一个重要原因——尤其是用\w显示完整路径的时候一旦你在某个深层嵌套目录里提示符就能占掉半个屏幕宽。两行化之后这个问题直接消失。3.3 \w和\W的选择逻辑说到路径显示我再多一句嘴。\w和\W的区别在于\w显示的是从根目录开始的完整路径如果你在主目录下还会用~缩写替换\W只显示当前目录的最后一个目录名。我在自己的机器上本机用\w因为本地目录结构我的看一眼完整路径能确认自己在哪但SSH到远程服务器的时候我会用\W因为服务器上的路径往往又长又没意义比如/var/www/html/wordpress/wp-content/themes/mytheme这种显示最后一级就够了。有需要的时候敲pwd随时看完整路径提示符太长了反而碍事。4. 颜色与高亮别让一堆花里胡哨的转义码毁了你的可读性改完结构下一步就是上色。这是让提示符真正好用也是最容易翻车的地方。颜色这关过了你的提示符才会从能看变为好看且高效。4.1 ANSI颜色编码是怎么回事终端颜色依赖ANSI转义序列基本格式是\e[样式;文字颜色;背景色m以\e[0m结束0代表恢复默认。这里面的数字编码记起来并不难平时用到的文字颜色就8种颜色前景色码背景色码黑3040红3141绿3242黄3343蓝3444紫3545青3646白3747除了颜色码还有几个常用的样式码1加粗、4下划线、5闪烁这个建议别用闪到怀疑人生、7反色。组合起来就是比如\e[1;32m表示加粗绿色文字\e[31;43m表示红字黄底如果你喜欢番茄炒蛋风格的提示符也不是不行。4.2 一个能直接用的彩色提示符示例先直观感受一下把下面这行粘到终端里export PS1\[\e[1;32m\]\u\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ 效果是这样的\u\h用加粗绿色显示冒号后紧跟的当前路径\w用加粗蓝色显示$符号恢复默认色。这个配色的好处是用户名和主机名一个色路径一个色视觉上分得非常清楚——你扫一眼就能定位路径不用费力在整行字符里找冒号在哪。注意观察代码里每个颜色序列前后都包了\[\e[...m\]和\[\e[0m\]。[和]我已经说过了是非打印字符标记而\e[0m是恢复默认的结束码它承担着防止颜色污染后续命令输出的任务——不加这个的话你敲命令的正文、甚至命令的输出结果都会变成绿色或蓝色直到下一个颜色初始化序列出现为止。4.3 256色和真彩色终端里还有更细腻的玩法如果你觉得8种颜色太粗糙终端其实还支持256色xterm-256color甚至24位真彩色。启用256色的语法是\e[38;5;颜色编号m前景色和\e[48;5;颜色编号m背景色编号范围0~255。比如export PS1\[\e[38;5;214m\]\u\[\e[0m\]\[\e[38;5;45m\]\h\[\e[0m\]:\[\e[38;5;39m\]\w\[\e[0m\]\$ 这个显示出来的橙色用户名和蓝色路径会比基本8色细腻不少。但这里有个前提条件你的终端模拟器得支持256色才行。Ubuntu默认的GNOME Terminal是支持的但某些老旧的终端工具可能不支持显示出来会变成一堆乱七八糟的字符。怎么确认自己的终端支持多少色执行echo $TERM如果输出xterm-256color那就是支持如果只是xterm那大概率只支持8色升级到256色需要改终端设置或安装支持256色的终端模拟器。真彩色的判断更麻烦一些可以直接用echo $COLORTERM如果输出truecolor那说明支持。不同的环境变量取值会影响后续的颜色选择策略这个多花一分钟查清楚不会亏。4.4 配色设计的一个核心原则关于配色我的个人原则很简单颜色是给信息分层的不是为了好看的。提示符里的每一块颜色都应该承载一个功能比如用户名/主机名用一种颜色用来快速区分我目前在哪台机器上路径用一种颜色用来快速定位我在哪个目录git状态如果有的话用一种颜色用来判断当前分支是否干净最后一个$或#保持默认或特殊色用来让你一眼知道当前权限如果你把提示符每个部分都涂成不同的彩虹色那和没有颜色没有区别——你依然需要逐段去读眼睛并不会因为颜色多了就变快。真正高效的提示符是扫一眼就知道重点在哪。5. 把临时修改变成永久配置.bashrc的正确打开方式前文我们都在临时环境里玩玩明白了就把它固化下来。这一步网上教程都写加到.bashrc里但很多细节点没讲清楚写错了轻则配置不生效重则终端打不开。5.1 应该写在.bashrc的什么位置打开~/.bashrc把自定义PS1的配置加到文件末尾即可。这是我推荐的位置因为文件末尾不会和其他系统预置的逻辑冲突预置的逻辑一般在文件中部或前面。加完之后保存然后source ~/.bashrc。一个完整的永久配置长这样# 自定义终端提示符 export PS1\[\e[1;32m\]\u\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ 这里有个细节我写export PS1...而不是PS1...。虽然不加export通常也能工作但加上更保险。另外注意整个赋值语句里用的是双引号。如果你用单引号里面的\u、\w这些转义序列不会被展开会原样显示成反斜杠加字母提示符直接变成\u\h:\w$一眼就能看出来是出问题了。这个问题非常常见几乎每过一阵都会有人在论坛里问为什么我的提示符显示的是\u不是用户名。5.2 区分交互式shell和登录shell这个坑不弄清楚会怀疑人生网上还有一种常见的写法是让你把PS1配置放在~/.profile或者/etc/profile里。这两种写法适用于不同的场景~/.bashrc在每次打开新的交互式bash时都会加载而~/.profile只在登录shell时加载。如果你用GNOME TerminalUbuntu默认的图形终端它打开的是交互式非登录shell所以你的PS1配置必须放在~/.bashrc里放~/.profile里很可能不生效。但如果你通过SSH登录远程服务器那个场景走的是登录shell的链路此时~/.profile里的配置会生效~/.bashrc不一定会被读取。更麻烦的是有些Ubuntu发行版在~/.profile里本来就有一段如果bash是交互式的且.bashrc存在就source它的逻辑但不同版本的系统行为还不完全一样。所以稳妥的做法是图形终端场景配置放.bashrcSSH登录场景配置放在.bashrc并显式在.profile里确保加载。实在拿不准自己在哪个环境就用echo $0看看——输出-bash或-zsh前面带横线的是登录shell不带的是非登录shell。5.3 在系统级配置里设置默认提示符如果你想给系统里所有用户做一套默认提示符比如给公司内部统一开发环境的标准化配置那需要改/etc/profile或者/etc/bash.bashrc这类系统级文件。这个操作需要sudo权限改之前建议先把原文件备份好sudo cp /etc/bash.bashrc /etc/bash.bashrc.bak sudo vim /etc/bash.bashrc在文件末尾加上同样的PS1配置。这样做的好处是所有新建用户都能继承到这套配置但要注意系统级配置文件在用户级配置之前加载用户自己的.bashrc会覆盖系统级设置。换句话说你改了系统级只是设了一个底线用户依然可以在自己的.bashrc里做个性化调整。对于大多数个人电脑而言改自己用户的.bashrc就够了真的不用去碰系统级文件除非你在维护一台多用户服务器。5.4 配置了不生效的排查清单我把最常见的改完不生效原因列成一个排查清单你照着逐条核对90%的问题都能解决症状原因解决方案提示符完全没变改的是.profile终端是交互式非登录shell把配置挪到.bashrc提示符显示\u\h原样字符使用了单引号而不是双引号改用双引号包裹修改.bashrc后新开终端也无变化.bashrc里可能有早期退出语句如exit检查并删除多余的exit颜色显示为[01;32m等乱码终端不支持ANSI转义序列或遇到被echo -e处理过的文本改用支持的终端确认转义字符为\e长命令换行时文字重叠颜色序列前忘了加\[和\]给所有非打印字符加\[和\]改完后终端报command not foundPS1被赋值为一个命令检查赋值语句是否被命令替换了比如用了反引号最后一条值得展开说一下如果你在赋值时不小心写成了export PS1date这种那PS1会变成date命令的输出结果一个固定的时间字符串而且每次打开shell时执行一次之后就不会再更新了提示符会显示一个冻结的时间。这个低级错误很容易犯尤其在你习惯用反引号做命令替换的时候。正确的方法是用\$()来做命令替换但说实话在PS1里想做动态信息更优雅的方案我会在下一节讲。6. 让提示符活起来动态信息、函数与分支状态的实战方案静态的提示符只能显示固定的几个信息但很多场景下我们希望提示符能感知当前环境并动态变化。比如在git仓库目录里自动显示当前分支、在Python虚拟环境里显示环境名、检测到当前目录不可写时显示警告色。这些效果靠单纯的PS1赋值做不到需要用bash函数和PROMPT_COMMAND来配合。6.1 PROMPT_COMMAND每次显示提示符前偷偷执行一段代码bash提供了一个叫PROMPT_COMMAND的环境变量它的值是一个命令或命令列表在每次显示PS1提示符之前会被执行。利用这个机制你可以在每次提示符刷新时动态计算PS1的值。举个例子我想让提示符显示当前git分支而且只在git仓库里才显示function _update_prompt() { if git rev-parse --git-dir /dev/null 21; then local branch$(git symbolic-ref --short HEAD 2/dev/null || echo detached) export PS1\[\e[1;32m\]\u\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\] (\[\e[1;35m\]$branch\[\e[0m\])\$ else export PS1\[\e[1;32m\]\u\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]\$ fi } PROMPT_COMMAND_update_prompt这段代码干了这么几件事每次显示提示符前先检查当前目录是不是git仓库通过git rev-parse --git-dir判断是的话就读取当前分支名用git symbolic-ref --short HEAD然后拼到提示符里紫色显示不是的话就用简化版的提示符。这套逻辑里我特意把git symbolic-ref失败的情况也兜底了比如你在一个HEAD游离的仓库里回退显示detached。不然的话你在那种状态下提示符会直接报错甚至闪退。这里要注意一个问题既然每次都在函数里重新export PS1了那就别再在~/.bashrc里单独设置静态PS1了否则函数里的赋值会被后面这行覆盖造成提示符改了但没完全改的诡异效果。我的习惯是一旦采用PROMPT_COMMAND方案静态PS1赋值那行直接注释掉不再保留两份配置。6.2 检测Python虚拟环境的小技巧很多人用Python开发开虚拟环境是家常便饭。默认情况下激活虚拟环境后提示符的前缀会变成(venv)但如果你自定义了PS1这个前缀可能就被覆盖了。更好的方式是自己在函数里检测function _update_prompt() { local venv if [[ -n $VIRTUAL_ENV ]]; then venv\[\e[1;33m\]($(basename $VIRTUAL_ENV))\[\e[0m\] fi # ... 以下拼接PS1时把$venv放到最前面 }VIRTUAL_ENV是Python虚拟环境激活时自动设置的环境变量值就是虚拟环境所在的目录路径。用basename取最后一级目录名显示成(venv)这样的形式并在黄色显示。这样虚拟环境激活与否一目了然不用每次敲echo $VIRTUAL_ENV去确认自己是不是在环境里。注意在函数内部用了局部变量local这是bash最佳实践避免污染全局变量。我在早期写这类函数时不用local后来排查其他问题时被自己留下的全局变量坑过——所以只要是函数内部的临时变量一律声明local这能省去很多后续调试的烦恼。6.3 左右分栏布局终端提示符里的双栏排版这个是比较进阶的玩法了。你有没有见过某些大神终端的提示符左边是常规的用户、路径右边靠终端的最右侧显示时间、git分支甚至系统负载左右分栏的效果在网络上的dotfiles仓库里非常常见看起来非常酷。实现原理其实不复杂利用ANSI转义序列里的光标定位功能。具体分三步保存当前光标位置\e[s把光标移动到屏幕最右端往前数N个字符的位置输出右侧内容恢复光标位置\e[u继续输出正常左侧提示符这里要计算终端的列数在bash里可以通过tput cols获取当前终端的列数。一个简单的实现function _right_prompt() { local right_text$(date %H:%M:%S) local right_width${#right_text} local term_width$(tput cols) local left_text\u\h:\w # 用ANSI转义先把光标移到右侧再恢复 echo -e \e[s\e[${term_width}G\e[${right_width}D${right_text}\e[u }把_right_prompt放到PROMPT_COMMAND里就能实现右侧显示时间。但这只是基础版处理起来还会有不少的细节魔鬼比如终端宽度变化时你拖拽窗口大小tput的值没及时刷新会导致排版错乱再比如右侧文本里的颜色序列会影响宽度计算。我在实际使用中自认为已经处理得足够健壮了最后还是偶尔会在某个奇怪的终端宽度组合下对不齐。所以如果你刚开始折腾建议先用简化版把右侧只放一个时间等思路完全理清了再逐步加复杂度不然调试起来真的会崩溃的。6.4 退出码感知一条命令失败后提示符立刻变色这个功能是我个人非常喜欢的强烈推荐你加上。原理也很简单bash会记录最后一条命令的退出码放在$?变量里。如果退出码是0说明命令成功非0则失败。我们可以在PROMPT_COMMAND里读取这个值然后根据成功/失败给提示符上不同的颜色。function _update_prompt() { local exit_code$? local reset\[\e[0m\] local color\[\e[1;32m\] # 默认绿色 if [[ $exit_code -ne 0 ]]; then color\[\e[1;31m\] # 失败时变红 fi export PS1${color}\u\h${reset}:\[\e[1;34m\]\w${reset}\$ }这里注意一个很微妙的点$?必须在函数最开始就取出来。因为一旦你在函数里执行了其他任何命令比如git rev-parse$?就会被那条命令的结果覆盖你拿到的不再是用户上一条命令的退出码了。我一开始就吃过这个哑巴亏排查半天发现自己拿到的永远是0因为函数体前面的判断逻辑本身就成功执行了。所以记住这个顺序先取退出码再做任何其他操作这是硬性纪律。当退出码非零时把提示符变红这会在你敲错命令、编译失败、测试挂掉的时候给你一个非常直观的视觉反馈。久而久之你甚至能形成条件反射——瞟一眼提示符颜色就知道上一条命令状态连回滚去翻输出都不用。7. 一个完整可用的提示符配置模板讲了这么多原理和代码片段最后我把我目前在Ubuntu主力机上用的整套配置分享出来。你可以直接复制也可以参考这个结构自己改。这是多年磨出来的一套方案包含了双行布局、用户名/主机名绿色加粗、路径蓝色、git分支紫色、Python虚拟环境黄色、错误变红、右侧时间显示。# 自定义终端提示符 function _current_git_branch() { if git rev-parse --git-dir /dev/null 21; then git symbolic-ref --short HEAD 2/dev/null || echo detached HEAD fi } function _current_python_env() { if [[ -n $VIRTUAL_ENV ]]; then echo ($(basename $VIRTUAL_ENV)) fi } function _right_side_prompt() { local time_str$(date %H:%M:%S) local term_width$(tput cols) local right_width${#time_str} echo -e \e[s\e[${term_width}G\e[${right_width}D\[\e[2;37m\]${time_str}\[\e[0m\]\e[u } function _update_prompt() { local exit_code$? local reset\[\e[0m\] local red\[\e[1;31m\] local green\[\e[1;32m\] local blue\[\e[1;34m\] local purple\[\e[1;35m\] local yellow\[\e[1;33m\] local gray\[\e[2;37m\] local user_color$green if [[ $exit_code -ne 0 ]]; then user_color$red fi local branch$(_current_git_branch) local branch_str if [[ -n $branch ]]; then branch_str ${purple}($branch)${reset} fi local venv$(_current_python_env) local venv_str if [[ -n $venv ]]; then venv_str${yellow}${venv}${reset} fi local first_line${venv_str}${user_color}\u\h${reset}:${blue}\w${reset}${branch_str} export PS1${first_line}\n\$ } PROMPT_COMMAND_update_prompt配置好之后的效果第一行展示所有上下文信息如果有虚拟环境显示黄色前缀用户名和主机名正常时是绿色、上一条命令失败时变红路径蓝色git分支紫色包裹在括号里第二行干净的只有一个$root用户会变成#。右侧还会有一行灰色的当前时间这个时间对用HISTTIMEFORMAT记录的历史命令来说非常有用有时能帮你判断自己刚才是否真的在某段时间执行了某条命令。关于右侧时间我最近在使用的版本里把它纳入了PROMPT_COMMAND一起执行选择在右侧显示时间的原因是它不占左侧的阅读空间而且时间信息属于偶尔瞄一眼就行的内容放在边缘正合适。如果你不需要右侧显示把_right_side_prompt这行从函数里去掉即可不影响其他部分。8. 折腾到一半遇到问题的排查思路最后再把常见的疑难杂症单独拎出来说说。有些问题不是配置语法的问题而是原理层面的理解偏差定位起来很费时间。8.1 提示符行宽计算错误症状、原理与修复这个前面已经提过值得再展开一次。当你在PS1里写了颜色码却忘了用\[和\]包裹时bash会把颜色码的字符长度也算进提示符宽度里。这些字符正常情况下是不可见的一旦算入宽度当你在接近行尾输入长命令时终端会在错误的列位置换行导致后续输入的内容覆盖在已有字符上面看起来像终端乱码。排查方法是逐行检查PS1定义把所有形如\e[...m的非打印序列都确认是否被\[和\]包裹。一个快速的检查思路是把PS1打印出来看长度——执行echo ${#PS1}然后手工估算去掉颜色码之后的实际显示长度两者如果差距很大那大概率就是漏了\[和\]。8.2 不同终端模拟器之间的兼容性差异同一套配置在GNOME Terminal里显示完美换到其他终端工具里就乱了。这种情况很常见。因为不同终端模拟器对ANSI转义序列的支持程度不一样尤其是256色和真彩色以及某些扩展序列如右侧光标的定位方式\e[${term_width}G。解决办法是尽量使用通用的转义序列把依赖特殊终端特性的功能单独写一个判断条件。比如用[[ $TERM *256color* ]]来判断终端是否支持256色支持才启用对应色值不支持就回退到基本8色。要记住你的配置不是只在你自己的终端里跑如果你要分享给别人使用兼容性测试不能省——至少要在GNOME Terminal、VS Code内置终端、以及通过SSH连接的远程终端相当于其他Linux环境的xterm这三个环境里各跑一遍看到的效果一致才算合格。8.3 不要在PS1里直接执行复杂命令网上有些大佬配置会在PS1里直接执行命令比如检查git分支、获取Python环境名全都在PS1的字符串拼接里完成。这种做法在概念上没问题但会导致一个性能隐患PS1会在每次显示提示符时评估如果里面跑了复杂的命令你每次敲回车都会有肉眼可感知的卡顿。尤其在大型git仓库里git status这类命令可能耗时不短。更好的做法就是我前面给的方案把动态逻辑放进PROMPT_COMMAND中执行的是赋值PS1这个动作本身而展示给PS1的最终字符串已经预先算好了。这个差别看起来微乎其微实际体验上差别很大——前者在大型仓库里每次提示符刷新都像卡住一样后者始终保持毫秒级响应。所以我的原则是能放进函数提前算好的就不要让PS1在展示时去动态计算。9. 一点关于折腾提示符这件事的最终体会其实提示符这个东西完全是不折腾也能用折腾好了很舒服的典型代表。我见过很多开发者系统装完用了三年都没动过提示符也见过有人把提示符折腾成了艺术品——不仅颜色绚烂还带emoji、带系统负载、带磁盘使用率。这个度怎么把握完全看个人喜好没有标准答案。但有一点我可以确定提示符是你和终端之间最频繁的交互界面。每天上百次看它花一两个小时把它调成自己看着舒服、信息组织合理的样子绝对是时间性价比极高的投资。每次source ~/.bashrc之后看到终端变成自己设计的模样那种这块地盘是我的的掌控感确实能提升一点日常写代码的愉悦度。如果你第一次改建议从小到大来先改结构单行变双行再上颜色再加动态信息最后再玩左右分栏。千万不要一次性把网上的终极配置整个搬过来因为那套配置里的每一个细节你都未必理解出了问题时根本无从下手。自己一步一步搭出来的配置哪怕看起来朴素也是你完全能掌控的系统。最后分享一个小建议改完配置之后花几分钟把你自己写的PS1配置和函数注释好存到Git仓库里比如dotfiles仓库。这样以后换新机器、换新工作一条命令就能把自己的终端配置全部恢复回来那种回家的感觉特别好。希望这篇文章能帮你少踩一些我当年踩过的坑早日拥有一套自己满意的终端提示符。