- 文档
- 知识库
【免费下载链接】claude-code-docs
claude-code-docs 是一个为 Claude Code 提供本地文档镜像的开源工具,而 install.sh 就是它的"全家桶"安装脚本:一个脚本同时完成全新安装、旧版迁移、自动更新和本地改动冲突处理四大任务。这篇文章带你逐段拆解这份 500 多行的 Bash 脚本,看看它如何在 macOS 和 Linux 上做到"一条命令装好、重复执行也不会弄脏你的环境"。
💡 适合人群:想读懂 shell 安装脚本的新手、考虑安装 claude-code-docs 的用户、以及想学习"防御式脚本编写"的同学。
一、安装脚本的全景地图
先建立整体认知。整个 install.sh 的执行流程可以概括为 8 个阶段:
| 阶段 | 对应函数/代码段 | 行号 |
|---|---|---|
| 1. 安全模式与版本声明 | 脚本头部 | L1-L14 |
| 2. 操作系统检测 | 内联代码 | L16-L27 |
| 3. 依赖检查 | 内联代码 | L29-L38 |
| 4. 扫描旧版安装 | find_existing_installations | L41-L115 |
| 5. 迁移旧安装 | migrate_installation | L117-L154 |
| 6. 安全更新 Git 仓库 | safe_git_update | L156-L297 |
| 7. 清理旧目录 | cleanup_old_installations | L299-L333 |
| 8. 配置 /docs 命令与自动更新 Hook | 内联代码 | L382-L493 |
理解了这张地图,下面的逐行精讲就只是在填空了。
二、脚本头部:三行代码定下"安全基调"
#!/bin/bash set -euo pipefail- 第 1 行:Shebang 声明使用 bash 解释器执行。
- 第 2 行是整个脚本最重要的"保险丝":
-e:任何命令失败立即退出,不会带着错误继续跑;-u:引用未定义变量直接报错,防止拼写错误导致逻辑跑偏;-o pipefail:管道中任意一环失败都会让整个管道返回失败,堵住"cmd | grep吞掉错误"的漏洞。
INSTALL_DIR="$HOME/.claude-code-docs" INSTALL_BRANCH="main"第 11-14 行把安装位置和目标分支固化为常量。所有后续逻辑都围绕这两个变量展开——这是迁移逻辑能稳定工作的前提:新位置永远固定,旧位置才需要被"找到"。
三、操作系统检测:只支持 macOS 与 Linux
if [[ "$OSTYPE" == "darwin"* ]]; then OS_TYPE="macos" elif [[ "$OSTYPE" == "linux-gnu"* ]]; then OS_TYPE="linux" else echo "❌ Error: Unsupported OS type: $OSTYPE" exit 1 fi这段代码(L17-L27)利用 bash 内置变量$OSTYPE做平台识别:macOS 对应darwin前缀,Linux 对应linux-gnu前缀。其他系统直接exit 1拒绝安装。
⚠️ 注意这里没有用命令行工具检测(如uname),而是用 shell 内置变量——零外部依赖、零 fork 开销,是平台检测的最佳实践。这与 README.md 中"Windows 尚未支持"的说明一致。
四、依赖检查:git、jq、curl 缺一不可
for cmd in git jq curl; do if ! command -v "$cmd" &> /dev/null; then echo "❌ Error: $cmd is required but not installed" exit 1 fi doneL29-L38 用command -v逐个探测三个依赖,缺失即退出:
- git:克隆和更新文档仓库的核心;
- jq:解析和改写
~/.claude/settings.json(Linux 上通常需apt install jq); - curl:辅助脚本模板丢失时的兜底下载通道。
💡 安装前报错 "git/jq/curl not found"?先把对应工具装上再跑一次脚本即可,这正是 README.md 故障排查章节提到的第一件事。
五、扫描旧版安装:三个线索找齐"前世今生"
find_existing_installations函数(L41-L115)是迁移功能的眼睛。它从三个线索收集历史安装路径:
线索 1:/docs 命令文件(L46-L71)
读取~/.claude/commands/docs.md,用正则同时匹配两代格式:
- v0.1 格式:
LOCAL DOCS AT: /path/to/claude-code-docs/docs/ - v0.2+ 格式:
Execute: /path/to/claude-code-docs/helper.sh
线索 2:settings.json 的 Hook 配置(L74-L104)
用jq提取所有PreToolUseHook 中命令里出现claude-code-docs字样的路径,再从复杂字符串里"剥"出目录部分(正则(.*/claude-code-docs)(/.*)?$截到项目根目录为止)。
线索 3:当前目录(L106-L109)
如果存在./docs/docs_manifest.json且当前目录不是新安装位置,说明用户正站在某个旧克隆目录里运行脚本,把$(pwd)也纳入候选。
最后一步很关键(L111-L114):
printf '%s\n' "${paths[@]}" | grep -v "^$INSTALL_DIR$" | sort -u去重 + 排除新安装位置——否则新装目录会被误判为"旧安装"而遭迁移。
六、迁移逻辑:先建新家,再决定旧宅去留
migrate_installation函数(L117-L154)的思路值得学习:
- 检查旧目录是否有未提交改动(L126-L134):进入旧目录执行
git status --porcelain,有任何输出就标记should_preserve=true。 - 优先在新位置全新克隆(L138):
git clone -b main ... $INSTALL_DIR,保证新家是干净的。 - 根据标记处理旧目录:
if [[ "$should_preserve" == "false" ]]; then rm -rf "$old_dir" # 无改动 → 安全删除 else echo "Old installation preserved at: $old_dir" # 有改动 → 原地保留 fi🛡️ 这里体现了一个重要原则:先完成新安装,再做任何破坏性操作。即使删除旧目录时断电,新家也完好无损;有未提交改动的旧目录则永远保留并明确告知用户,绝不静默丢弃。
七、safe_git_update:冲突处理的核心战场
这是全脚本最长、也最精巧的函数(L156-L297),专门负责"安全更新已有仓库"。它的策略是分层降级:
第一步:乐观更新(L186-L188)
if git pull --quiet origin "$target_branch" 2>/dev/null; then return 0 fi90% 的情况下普通git pull就成功了,直接返回,快进快出。
第二步:悲观接管(L190-L292)
pull 失败后,先git fetch拉取远端(离线时给出 "offline?" 提示并返回失败)。然后进入冲突诊断,检查三类脏状态:
| 检查项 | 命令特征 | 含义 |
|---|---|---|
| 合并冲突 | git status --porcelain中的UU/AA/DD | 上次合并没处理完 |
| 已修改文件 | 非??开头的 porcelain 输出 | 本地改过文件 |
| 未跟踪文件 | ^??输出(忽略.tmp/.log/.swp临时文件) | 目录里有新文件 |
一个贴心的例外:docs_manifest.json
诊断时反复出现同一个过滤条件:
grep -v "docs/docs_manifest.json"docs/docs_manifest.json 是文档清单文件,脚本会自动更新它,因此它的改动和冲突属于"预期内噪音",被排除在告警之外。这是"区分用户数据与工具数据"的教科书式处理(L495 的注释也再次强调了这一点)。
用户确认:破坏性操作前必须问
如果检测到真实冲突(L232-L256),脚本会列出问题清单并询问:
Continue and discard local changes? [y/N]:默认值是N——不输入就是取消,本地改动原样保留;明确输入y才继续。注意分支切换场景(L200-L202)则跳过询问直接清理,因为切换分支属于脚本自己发起的操作。
强制归位:四板斧重置到干净状态
git merge --abort >/dev/null 2>&1 || true git rebase --abort >/dev/null 2>&1 || true git reset >/dev/null 2>&1 || true git checkout -B "$target_branch" "origin/$target_branch" git reset --hard "origin/$target_branch" git clean -fdL278-L292 依次:中止进行中的 merge/rebase → 清空陈旧索引 →-B强制重建分支引用(顺带修复 detached HEAD)→ 硬重置到远端 → 清掉未跟踪文件。每一步都带|| true容错,确保某步没东西可清时不会因set -e中断整个流程。
八、清理旧安装:只删"干净的"
cleanup_old_installations(L299-L333)遍历第五步收集到的所有旧目录,判断规则很简单:
- 是 Git 仓库且
git status --porcelain为空 → 删除,显示 "✓ Removed (clean)"; - 有未提交改动 → 保留,显示 "⚠️ Preserved";
- 不是 Git 仓库(可能是手动拷贝的安装)→ 保守保留。
它依赖全局数组OLD_INSTALLATIONS,该数组在任何配置被修改之前就已填充(L338-L348 的注释解释了原因:先改配置再扫描,线索就找不到了)。
九、主流程:一个 if/else 决定三种命运
L335-L380 是脚本的主干,逻辑清晰得像分岔路口:
新位置 ~/.claude-code-docs 已存在? ├── 是 → safe_git_update 更新之(更新场景) └── 否 → 找到旧安装? ├── 是 → migrate_installation 迁移(迁移场景) └── 否 → git clone 全新安装(新装场景)三种场景殊途同归:执行完后,工作目录一定停在$INSTALL_DIR,为后续统一配置做准备。
十、安装辅助脚本:模板复制 + curl 双保险
L386-L403 安装运行时真正干活的辅助脚本 scripts/claude-docs-helper.sh.template:
- 首选:把仓库里的模板复制为
~/.claude-code-docs/claude-docs-helper.sh并chmod +x; - 兜底:模板文件意外丢失时(L393 的 "attempting recovery"),用
curl -fsSL直接从远端下载该单个文件; - 两条路都失败才
exit 1终止。
这个"本地文件 + 远程单文件下载"的双通道设计,让脚本对仓库损坏这类边缘情况有了自愈能力。
十一、生成 /docs 命令:把用法写进命令文件
L405-L454 用cat > ... << 'EOF'生成~/.claude/commands/docs.md。注意几个细节:
- 先
mkdir -p ~/.claude/commands确保目录存在; - 旧的
docs.md直接覆盖重写——即使旧命令指向已删除的旧路径也能被自动修正(L405 注释 "Always update command"); - 命令文件里写明了用法示例和期望输出格式(
/docs hooks、/docs -t、/docs whats new等),最后指明实际执行入口:Execute: ~/.claude-code-docs/claude-docs-helper.sh "$ARGUMENTS"。
这样 Claude Code 读到/docs命令时,会知道如何把参数传递给辅助脚本。辅助脚本内部的read_doc、show_freshness、whats_new等函数详见 scripts/claude-docs-helper.sh.template。
十二、配置自动更新 Hook:jq 两步走
L456-L493 把~/.claude/settings.json里的 Hook 更新为调用辅助脚本的hook-check子命令,采用"先删后加"的两步 jq 策略:
- 第一步删除所有含
claude-code-docs的旧 Hook(L468)——不管旧安装在哪条路径下,一次清理干净; - 第二步追加新 Hook(L471):匹配
Read工具,读取文档文件前触发自动同步检查。
中间产物写入.tmp再覆盖回原文件,避免 jq 读写同一文件出错。若settings.json不存在,则用jq -n从零生成完整结构(L474-L492)。
十三、收尾:成功信息与可用主题一览
脚本最后(L500-L517)打印安装成功信息、三个典型用法示例,并用ls + grep + column以多栏排版列出docs/目录下所有可用的文档主题,最后提醒重启 Claude Code 后自动更新才生效。
想移除这套集成?运行~/.claude-code-docs/uninstall.sh或查看 UNINSTALL.md 的手动卸载步骤即可。
十四、总结:这个安装脚本教会我们的 5 件事
| 技巧 | 体现位置 | 一句话点评 |
|---|---|---|
| 严格错误模式 | set -euo pipefail | 脚本安全的底线 |
| 乐观-悲观分层策略 | safe_git_update | 先试简单方案,失败再升级 |
| 破坏性操作前询问 | read -p "...[y/N]" | 默认值选 N,保守即正义 |
| 区分工具数据与用户数据 | 过滤docs_manifest.json | 减少无谓告警的关键 |
| 先建新、再删旧 | migrate_installation | 任何时刻断电都不丢数据 |
看完 install.sh 的全貌你会发现:所谓"单个脚本搞定一切",本质是把状态扫描、版本迁移、冲突仲裁、配置写入四件事都做了防御性设计。下次再遇到curl ... | bash风格的安装脚本,不妨也逐段读一读——读懂了它,你才真正知道它在你机器上做了什么。
- 文档
- 知识库
【免费下载链接】claude-code-docs
相关推荐
Docs数据迁移工具开发:自定义脚本与批处理优化
Docs数据迁移工具开发:自定义脚本与批处理优化 在企业级文档协作平台的运维过程中,数据迁移往往是最棘手的环节之一。无论是系统升级、存储架构调整,还是跨平台数据
前端后端内容协同知识管理解剖claude-token.py:一个Python脚本如何桥接Claude Code与Ghostty Blackhole
解剖claude token.py:一个Python脚本如何桥接Claude Code与Ghostty Blackhole Ghostty Blackhole
如何5分钟快速安装claude-code-docs:从检查依赖到首次运行/docs命令
如何5分钟快速安装claude code docs:从检查依赖到首次运行/docs命令 claude code docs 安装 只需 5 分钟:它是 Claud
文档知识库
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考