starship 是跨 shell 的提示符工具,Rust 写的单文件 exe。它接管命令行前面那一行:显示当前目录、git 分支和改动、语言版本、上一条命令的耗时,样式由一份 TOML 配置决定。5 种 shell 共用同一个 exe,不用为每个终端各写一套。
提示符有个绕不开的代价:每敲一次回车,它都要重新跑一遍。实测在普通目录里 170.3 毫秒,进 git 仓库变成 627.1 毫秒,慢了 3.7 倍。
装上之后要 init 一次
Release 页给的是单个 starship.exe。放进 PATH 之后,还要让 shell 知道每次画提示符要调它,这一步靠 init:
> starship init powershell
Invoke-Expression (&starship init powershell --print-full-init | Out-String)
> starship --version
starship 1.27.0
把 init 那一行加进 shell 的启动脚本,重开终端就生效,bash、zsh、fish、cmd 各有对应写法。exe 本身不驻留,每次调用起一个新进程,这也是后面耗时的来源。
提示符长这样
普通目录: wb_cache\lab\art5
❯
git 仓库: wb_cache\lab\art5 on master [?]
❯
目录是青色,分支是紫色,方括号里那个问号表示有未跟踪文件。测试仓库里放了 2 个文件,1 个已经提交、1 个还没加进索引,所以问号出现了。这些信息全部来自目录扫描和 git 命令,不是预先写死的。用 starship explain 可以看当前提示符每一段是什么:
> starship explain
wb_cache\lab\art5 - The current working directory
❯ - A character (usually an arrow) beside where text is entered in your terminal
每个模块花多少时间,它自己会算
starship timings 会把当前提示符里每个模块的耗时打出来,这就是排查卡顿的入口。同一个 exe 在两个目录下:
| 模块 | 普通目录(毫秒) | git 仓库(毫秒) |
|---|---|---|
| git_status | 0 | 280 |
| directory | 1 | 189 |
| python | 149 | 0 |
| git_branch | 0 | 1 |
| battery | 1 | 1 |
| character | 1 | 1 |
普通目录里最贵的是 python 模块,149 毫秒,因为目录下有 .py 文件,它要去问解释器版本。git 仓库里这两个模块都不在,换成 git_status 280 毫秒和 directory 189 毫秒。
directory 从 1 毫秒涨到 189 毫秒,原因是 git 仓库里它要多做一步:判断当前目录是不是仓库的一部分。这一步比读一个路径字符串贵两个数量级。
整条提示符的总耗时
模块耗时不等于总耗时,exe 启动和模块调度都要算。同一个 exe、同一份默认配置,各跑 15 次取平均:
| 场景 | 平均(毫秒) | 范围(毫秒) |
|---|---|---|
| 普通目录 | 170.3 | 160.3 ~ 199.6 |
| git 仓库 | 627.1 | 585.0 ~ 715.7 |
| git 仓库 · 关掉 git_status | 332.4 | — |
| 关掉 python 与 package · 普通目录 | 163.2 | — |
| 关掉 python 与 package · git 仓库 | 631.7 | — |
| git 仓库相对普通目录 | 3.7 倍 | — |
关掉 python 和 package 只从 170.3 降到 163.2 毫秒,几乎没有变化,因为那 149 毫秒是 timings 模式单独跑模块的数字,正常画提示符时它被跳过。真正拖时间的是 git_status:只关这一个,git 仓库从 627.1 降到 332.4 毫秒。
慢的话怎么救
配置在 ~/.config/starship.toml,Windows 上是 %USERPROFILE%\.config\starship.toml。starship module --list 列出 108 个模块,默认配置只用到其中 7 个,剩下 101 个要用才开。关掉不看的模块是最直接的办法,3 个模块的配置只有 6 行:
[git_status]
disabled = true
[python]
disabled = true
[package]
disabled = true
关掉 git_status 之后,那个 [?] 标记就没了,未提交的改动不再显示,换回来的是 294.7 毫秒。要不要这个交换,看你在仓库里敲命令的频率。
另一条路是限制扫描深度。directory 模块支持 truncation_length 和 truncate_to_repo,把路径截短能省掉一部分遍历。starship preset 里有几套现成配置,用 preset 名字直接生成,不用手写 TOML。
配置写坏会静默降级
> starship prompt # 配置文件里写的是 "this is not toml"
wb_cache\lab\art5 ❯ [ERROR] - (starship::config):
Unable to parse the config file: TOML parse error
配置文件语法错了,它不会崩,而是把错误打进提示符里,然后按默认配置继续画。改配置时看到提示符后面多出一段 [ERROR],那就是解析失败。同样的错误不会让退出码变成非 0,脚本里没法靠退出码判断配置对不对。
写了不存在的模块名(比如 [not_a_module]),它直接忽略,也不报警,提示符看起来和正常一样。配置里的键名拼错同样静默,这是排查时最容易漏的一类问题。
用 starship module 调用一个不存在的模块才会明确报错:
> starship module nosuchmodule
Error: Unknown module nosuchmodule. Use starship module --list to list out all supported modules.
这一条退出码仍然是 0,错误只写在 stderr 里。
什么时候别用
在超大仓库里频繁操作。git 仓库里 627.1 毫秒意味着每次回车都要等半秒多,比打字本身还慢。仓库越大、改动文件越多,git_status 越慢。
只想要一个静态提示符。如果需求只是「显示路径和分支」,shell 内置的 prompt 变量改 2 行就够了,不用引入一个每次都起进程的 exe。
想看完整的默认配置。starship print-config 会输出 28037 字节的 TOML,7 个模块和 1.27.0 的默认值全在里面,改之前先看一遍比猜参数名靠谱。
还没测的两项:超大仓库(几万文件)下的 git_status 耗时曲线 / 与 zsh 自带 git 提示符插件的对比。前者需要造一个大仓库,后者要在 macOS 或 Linux 上跑。










