Spaceship Prompt 的 Docker Compose 状态指示模块(docker_compose)配置与实现解析
【免费下载链接】spaceship-prompt🚀✨ Minimalistic, powerful and extremely customizable Zsh prompt项目地址: https://gitcode.com/gh_mirrors/sp/spaceship-prompt
导读
本文围绕 Spaceship Prompt 的docker_compose模块展开,讲解它如何通过一条命令读取当前目录下 Docker Compose 项目中每个容器的运行状态,并将状态以"容器名首字母 + 颜色"的形式直接渲染进 Zsh 提示符。读完本文,你将掌握该模块的显示触发条件、9 个可调配置项及其默认值、状态着色规则,以及它背后"upsearch 探测 compose 文件 → 解析docker-compose ps输出 → 按状态着色拼接"的完整实现链路,并了解如何通过SPACESHIP_PROMPT_ORDER把它接入自己的提示符。
模块定位:多容器应用状态的可视化窗口
docker_compose是 Spaceship Prompt(spaceship.zsh)众多内置 section 之一。它的核心职责非常聚焦:展示当前目录 Docker Compose 项目中各个容器的实时运行状态。
- 它只在包含
docker-compose.yml、docker-compose.yaml、compose.yml或compose.yaml的项目目录中显示(见 docs/sections/docker_compose.md); - 它为每一个容器输出一个由容器名首字母大写构成的"指示符"(indicator),并按容器状态着色;
- 该模块默认异步渲染,不会阻塞提示符的刷新。
状态判定与着色规则
模块为每个运行中的容器显示一个字母标记,颜色对应容器状态:
| 容器状态 | 颜色 | 含义 |
|---|---|---|
Up/running | green(SPACESHIP_DOCKER_COMPOSE_COLOR_UP) | 容器正在运行 |
Paused/paused | yellow(SPACESHIP_DOCKER_COMPOSE_COLOR_PAUSED) | 容器已暂停 |
其他状态(如Exit、exited) | red(SPACESHIP_DOCKER_COMPOSE_COLOR_DOWN) | 容器已停止或出错 |
以上规则与官方文档一致(见 docs/sections/docker_compose.md 的状态说明),而其判定逻辑可以精确地在 sections/docker_compose.zsh 中找到:
if [[ "$line" == *"Up"* ]] || [[ "$line" == *"running"* ]]; then color="$SPACESHIP_DOCKER_COMPOSE_COLOR_UP" elif [[ "$line" == *"Paused"* ]] || [[ "$line" == *"paused"* ]]; then color="$SPACESHIP_DOCKER_COMPOSE_COLOR_PAUSED" else color="$SPACESHIP_DOCKER_COMPOSE_COLOR_DOWN" fi可以看到源码采用大小写双匹配的字符串判断:凡输出行包含Up或running即视为运行中,包含Paused或paused即视为暂停,其余一律落入"停止/错误"分支。这正是为什么容器名的首字母会以不同颜色呈现在提示符中——一眼即可判断哪些服务健康、哪些需要处理。
配置参数一览
模块的所有行为均可通过环境变量定制。完整参数表如下(取自 docs/sections/docker_compose.md 的 Options 章节,默认值与 sections/docker_compose.zsh 中的初始化代码一致):
| 变量 | 默认值 | 含义 |
|---|---|---|
SPACESHIP_DOCKER_COMPOSE_SHOW | true | 是否显示该 section |
SPACESHIP_DOCKER_COMPOSE_ASYNC | true | 是否异步渲染该 section |
SPACESHIP_DOCKER_COMPOSE_PREFIX | runs | section 的前缀 |
SPACESHIP_DOCKER_COMPOSE_SUFFIX | $SPACESHIP_PROMPT_DEFAULT_SUFFIX | section 的后缀 |
SPACESHIP_DOCKER_COMPOSE_SYMBOL | 🐙 | section 开头显示的符号 |
SPACESHIP_DOCKER_COMPOSE_COLOR | cyan | section 整体颜色 |
SPACESHIP_DOCKER_COMPOSE_COLOR_UP | green | 运行中容器的指示符颜色 |
SPACESHIP_DOCKER_COMPOSE_COLOR_DOWN | red | 已停止/出错容器的指示符颜色 |
SPACESHIP_DOCKER_COMPOSE_COLOR_PAUSED | yellow | 已暂停容器的指示符颜色 |
需要留意的细节:
- PREFIX 默认值自带空格:源码中
SPACESHIP_DOCKER_COMPOSE_PREFIX="${SPACESHIP_DOCKER_COMPOSE_PREFIX="runs "}",即默认前缀是runs(注意结尾空格),渲染后形如runs 🐙 A D W; - SUFFIX 回退到全局默认后缀:
SPACESHIP_DOCKER_COMPOSE_SUFFIX默认取$SPACESHIP_PROMPT_DEFAULT_SUFFIX(其默认值为一个空格,见 docs/config/prompt.md)。这一"未设置则回退全局默认"的模式在整个项目中普遍存在,例如 docs/advanced/creating-section.md 中的SPACESHIP_FOOBAR_SUFFIX同样如此。
自定义示例
在.zshrc中加载 Spaceship 后、Prompt 渲染前设置环境变量即可覆盖默认值,例如:
# 关闭该 section SPACESHIP_DOCKER_COMPOSE_SHOW=false # 自定义前缀与符号 SPACESHIP_DOCKER_COMPOSE_PREFIX="compose: " SPACESHIP_DOCKER_COMPOSE_SYMBOL="🧩 " # 自定义状态颜色 SPACESHIP_DOCKER_COMPOSE_COLOR_UP="blue" SPACESHIP_DOCKER_COMPOSE_COLOR_DOWN="magenta" SPACESHIP_DOCKER_COMPOSE_COLOR_PAUSED="white"如何把该 section 加入提示符
docker_compose默认是否显示取决于SPACESHIP_PROMPT_ORDER。若它未出现在你的提示符中,可通过SPACESHIP_PROMPT_ORDER显式加入:
SPACESHIP_PROMPT_ORDER=( user # 用户名 dir # 当前目录 git # Git 状态 docker_compose # Docker Compose 容器状态 char # 末尾提示符符号 )若已显式加入但仍不显示,请对照排查:确认当前目录(或向上任意父目录)存在四个目标文件名之一、确认docker-compose命令可用、确认docker-compose ps -a能正常输出容器信息。
实现原理:从探测文件到渲染指示符
该 section 的全部逻辑集中在 sections/docker_compose.zsh,整体分三步。了解这些细节,有助于你在排查"为什么没显示/颜色不对"时快速定位。
第一步:前置条件检查(文件探测 + 命令可用性)
spaceship_docker_compose() { [[ $SPACESHIP_DOCKER_COMPOSE_SHOW == false ]] && return spaceship::exists docker-compose || return local docker_compose_globs=('docker-compose.y*ml' 'compose.y*ml') spaceship::upsearch -s $docker_compose_globs || return ... }- 若
SPACESHIP_DOCKER_COMPOSE_SHOW为false,直接返回,不渲染任何内容; spaceship::exists docker-compose检测系统中是否存在docker-compose可执行文件;spaceship::upsearch -s docker-compose.y*ml compose.y*ml从当前目录逐级向上查找compose 文件(-s为静默模式,只返回成功/失败,不打印路径)。upsearch的实现见 lib/utils.zsh:它会一路向父目录查找,直到遇到.git或.hg目录边界为止,找到即成功返回,找不到则返回非零状态——这也是该模块只在"Compose 项目目录"内显示的根源。
第二步:调用 docker-compose 读取容器列表
local containers="$(docker-compose ps -a 2>/dev/null | tail -n+2)" [[ -n "$containers" ]] || returndocker-compose ps -a列出项目内全部容器(含已停止的),tail -n+2去掉表头行;- 若输出为空(没有容器),直接返回,section 不显示。
关于输出格式,仓库中的测试桩 tests/stubs/docker-compose 模拟了真实输出:
Name Command State Ports --------------------------------------------------------------------------------------------------------- adminer entrypoint.sh docker-php-e ... Up 0.0.0.0:8080->8080/tcp,:::8080->8080/tcp db docker-entrypoint.sh mariadbd Exit 255 3306/tcp watchtower /watchtower Paused 8080/tcp可以看到State列包含Up/Exit/Paused等状态词,这正是上文中字符串匹配判定颜色的依据。
第三步:逐行解析并着色拼接
while IFS= read -r line; do local letter_position=$(echo $line | awk 'match($0,"_"){print RSTART}') local letter=$(echo ${line:$letter:1} | tr '[:lower:]' '[:upper:]') local color="" [[ -z "$letter" ]] && continue if [[ "$line" == *"Up"* ]] || [[ "$line" == *"running"* ]]; then color="$SPACESHIP_DOCKER_COMPOSE_COLOR_UP" elif [[ "$line" == *"Paused"* ]] || [[ "$line" == *"paused"* ]]; then color="$SPACESHIP_DOCKER_COMPOSE_COLOR_PAUSED" else color="$SPACESHIP_DOCKER_COMPOSE_COLOR_DOWN" fi statuses+="$(spaceship_docker_compose::paint $color $letter)" done <<< "$containers"- 对每行容器记录,用
awk找到名字中第一个_的位置(Compose 生成的容器名形如项目名_服务名_序号),取该位置的首字母并转为大写作为指示符; - 按上述状态规则判定颜色后,调用工具函数
spaceship_docker_compose::paint生成 ANSI 着色文本:
spaceship_docker_compose::paint() { local color="$1" text="$2" echo -n "%{%F{$color}%}$text%{%f%}" }最终通过spaceship::section输出带前缀、后缀、符号的完整 section:
spaceship::section \ --color "$SPACESHIP_DOCKER_COMPOSE_COLOR" \ --prefix "$SPACESHIP_DOCKER_COMPOSE_PREFIX" \ --suffix "$SPACESHIP_DOCKER_COMPOSE_SUFFIX" \ --symbol "$SPACESHIP_DOCKER_COMPOSE_SYMBOL" \ "$statuses"测试验证:期望渲染结果
仓库用 shunit2 为该模块编写了完整测试,见 tests/docker_compose.test.zsh:
test_docker_compose_no_files:目录中没有 compose 文件时,section 完全不渲染(expected为空字符串);test_docker_compose_configs:依次在目录中创建docker-compose.yml、docker-compose.yaml、compose.yml、compose.yaml四种文件,断言渲染结果为%{%B%}runs %{%b%}%{%B%F{cyan}%}🐙 %{%F{green}%}A%{%f%}%{%F{red}%}D%{%f%}%{%F{yellow}%}W%{%f%}%{%b%f%},即runs 🐙 A D W——其中A(adminer)绿色、D(database)红色、W(watchtower)黄色。
该测试同时验证了两个关键事实:四种 compose 文件名都能触发渲染,且状态着色与 sections/docker_compose.zsh 的判定逻辑完全对应。
常见问题与排查思路
section 完全不显示
- 检查当前目录及所有父目录(直到 Git/Hg 仓库边界)是否存在四种 compose 文件之一;
- 确认
docker-compose命令已安装并在PATH中(源码通过spaceship::exists检测); - 确认
docker-compose ps -a有输出(无容器时 section 同样不显示)。
容器状态与颜色不符合预期
- 状态判定依赖
docker-compose ps输出中的Up/running/Paused/paused等关键词,若自定义过docker-compose ps的格式化输出,可能影响匹配结果; - 提示符中请启用颜色(如
TERM支持 256 色,测试中即设定了TERM="xterm-256color")。
- 状态判定依赖
希望关闭异步渲染
- 设置
SPACESHIP_DOCKER_COMPOSE_ASYNC=false即可(模块默认异步,参见文档说明与 sections/docker_compose.zsh)。
- 设置
小结
docker_composesection 用最直观的"首字母 + 颜色"把多容器应用的健康状态搬进了提示符:runs 🐙前缀、青色 section、绿/黄/红三色容器指示符。理解它的四类触发条件、九项配置与三步渲染流程(文件探测 → 命令读取 → 状态着色),你就能在需要时自由定制,也能快速定位任何显示异常。若想深入了解 section 的通用编写规范,可继续阅读 docs/advanced/creating-section.md;若需查阅该 section 的配置总览,可对照 docs/config/intro.md。
【免费下载链接】spaceship-prompt🚀✨ Minimalistic, powerful and extremely customizable Zsh prompt项目地址: https://gitcode.com/gh_mirrors/sp/spaceship-prompt
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考