06 · 长期工具链
第一次搭博客花 1 个下午是值得的——只要把流程工具化,第二次只要 30 分钟。这一篇讲怎么把流程沉淀成可复用工具。
一、目录哲学:~/.config/{platform}/
为什么用这个路径
~/.config/是 XDG 标准目录,专门放配置——所有现代 unix 工具都遵循- 按
{platform}分组(gitee / github / vercel / 等),一个平台一个文件夹 - 三件套的独立性使部分泄露不影响整体——比如 token 暴露了换一个,user.env 不动
标准三件套
~/.config/{platform}/
├── token # 平台 API token(权限 600,仅自己可读)
├── user.env # 用户信息:用户名 / 邮箱(权限 600)
└── {platform}.sh # 命令函数库(权限 700)为什么不放在 ~/.ssh/
~/.ssh/ 按惯例只放 SSH 相关——key、known_hosts、config。把 API token 混进去不规范。
二、长期工具的设计原则
原则 1:函数 > 别名 > 脚本
| 形式 | 优势 | 劣势 |
|---|---|---|
| shell 函数(推荐) | 同一个 shell 上下文、可访问环境变量、更灵活 | 必须 source 加载 |
| 别名 (alias) | 简单 | 不支持参数、不支持多行逻辑 |
| 独立脚本 | 跨 shell 通用 | 启动开销、需放在 PATH 里 |
原则 2:命令命名遵循 {平台}-{动作} 模式
gitee-whoami # 一目了然
github-init-and-push # 即使忘了,敲 `gitee-` 按 Tab 也能补全原则 3:失败时给出可读错误
_gitee_check_env() {
if [ -z "$GITEE_TOKEN" ]; then
echo "❌ GITEE_TOKEN 未设置(检查 ~/.config/gitee/token)" >&2
return 1
fi
}原则 4:每个函数都该单独跑通
不要写一个巨型 setup-everything 函数。拆成原子操作:
gitee-whoami # 测 token
gitee-upload-key # 上传公钥
gitee-new-repo # 建仓库
gitee-init-and-push # 高层组合:当前目录一键变 Gitee 仓库三、Gitee 函数库(参考实现)
完整代码见 scripts/gitee.sh(GitHub 仓库)。核心命令:
| 命令 | 用途 |
|---|---|
gitee-whoami | 测 token 是否有效 |
gitee-new-repo <name> [描述] [private] | 创建新仓库 |
gitee-upload-key [title] | 上传当前 SSH 公钥 |
gitee-init-and-push <name> | 当前目录一键变 Gitee 仓库 |
安装方式
mkdir -p ~/.config/gitee
cp scripts/gitee.sh ~/.config/gitee/gitee.sh
chmod 700 ~/.config/gitee/gitee.sh
# 把 token 和 user 信息写进去
echo '你的token' > ~/.config/gitee/token
chmod 600 ~/.config/gitee/token
cat > ~/.config/gitee/user.env <<EOF
export GITEE_USER="你的用户名"
export GITEE_NAME="你的姓名"
export GITEE_EMAIL="你的邮箱"
EOF
chmod 600 ~/.config/gitee/user.env
# 加到 shell rc
echo '
# Gitee CLI helpers
[ -f ~/.config/gitee/gitee.sh ] && source ~/.config/gitee/gitee.sh
' >> ~/.zshrc
# 重新加载
source ~/.zshrc
gitee-whoami # 测试四、GitHub 函数库(参考实现)
完整代码见 scripts/github.sh(GitHub 仓库)。命令同 Gitee 风格:
| 命令 | 用途 |
|---|---|
github-whoami | 测 token |
github-new-repo <name> [描述] [private] | 建仓库 |
github-upload-key | 上传公钥 |
github-init-and-push <name> | 一键初始化 |
关键差异
GitHub API 的 token 用 Authorization: token <TOKEN> header(不是 query param),这是和 Gitee 主要的实现差异。
五、Token 轮换策略
两类凭证的差异
| 凭证 | 用途 | 长期需求 | 轮换频率 |
|---|---|---|---|
| SSH key | git push/pull | 一次配好用一辈子 | 不轮换 |
| API Token | API 操作(建仓库等) | 长期保留 | 视风险 |
三种轮换策略
| 策略 | 适合 | 操作 |
|---|---|---|
| 不轮换 | 个人项目 | token 长期保留在 ~/.config/{platform}/token(权限 600) |
| 定期轮换 | 关注安全 | Token 设 90 天过期 → 到期生成新 token 覆盖文件 |
| 每次轮换 | 高敏感 | 用 fine-grained token + 限定仓库 + 短过期 |
💡 实际推荐:90 天定期轮换——养成习惯但不太频繁。
Token 过期后的续期命令(一行)
echo '新token' > ~/.config/{platform}/token && chmod 600 ~/.config/{platform}/token六、模板文件清单
参见 templates/ 目录(GitHub 仓库):
| 文件 | 用途 |
|---|---|
package.json | VitePress 项目最小依赖 |
vercel.json | Vercel 部署配置 |
vitepress-config.mts | VitePress 配置模板(含 rewrites、sidebar 等占位符) |
gitignore | 含 macOS、IDE、Node、VitePress 忽略 |
README.template.md | 仓库主页模板 |
一键拷贝到新主题
cd ~/notes/我的新主题
# 拷模板
cp ~/notes/personal-blog-playbook/templates/{package.json,vercel.json,gitignore} .
mv gitignore .gitignore
mkdir -p .vitepress
cp ~/notes/personal-blog-playbook/templates/vitepress-config.mts .vitepress/config.mts
# 然后改一下里面的 title / sidebar / rewrites七、新主题完整工作流(30 分钟)
假设环境就绪
- ✅ Node.js 已装
- ✅ SSH key 已上传到 Gitee 和 GitHub
- ✅
~/.config/{gitee,github}/已配置好 - ✅
~/.zshrc已 source 函数库
30 分钟流程
# 1. 创建主题目录(1 分钟)
mkdir -p ~/notes/我的新主题
cd ~/notes/我的新主题
# 2. 写第一篇内容(10 分钟)
cat > README.md <<EOF
# 我的新主题
EOF
cat > 01-入门.md <<EOF
# 入门
内容...
EOF
# 3. 拷模板(1 分钟)
cp ~/notes/personal-blog-playbook/templates/{package.json,vercel.json,gitignore} .
mv gitignore .gitignore
mkdir -p .vitepress
cp ~/notes/personal-blog-playbook/templates/vitepress-config.mts .vitepress/config.mts
# 4. 改 vitepress 配置:sidebar / rewrites / title(5 分钟)
# 用编辑器手动改
# 5. 装依赖 + 测试(2 分钟)
npm install
npm run dev # 浏览器看一眼,OK 就 ctrl+C
# 6. 创建 Gitee 仓库 + 推送(1 分钟)
gitee-init-and-push my-new-topic "我的新主题"
# 7. 创建 GitHub 仓库 + 推送(1 分钟)
github-init-and-push my-new-topic
# 8. 在 Vercel 网页 Import GitHub 仓库(5 分钟)
# 手动操作:vercel.com → Add New → Project → Import → Deploy
# 9. 拿到链接,关 Authentication(如果默认开了)(2 分钟)
# 完成:博客上线后续日常更新
cd ~/notes/我的新主题
# 写新内容...
git add . && git commit -m "feat: ..."
git push --all
# 30 秒后博客自动更新八、维护这套工具链
何时更新模板
每次踩到新坑 → 修复后 → 把修复同步到模板:
# 比如 vercel.json 加了新字段
cp ~/notes/我的主题/vercel.json ~/notes/personal-blog-playbook/templates/vercel.json
cd ~/notes/personal-blog-playbook
git add templates/vercel.json
git commit -m "templates: 更新 vercel.json,加了 XXX 字段"何时更新文档
发现新模式 / 新坑 → 写到对应阶段的 docs 里:
cd ~/notes/personal-blog-playbook
vim docs/05-deploy.md
git commit -am "docs: 增加 XXX 错误的解决方案"案例研究存档
每次新主题搭建完,写一个简短案例放到 case-studies/:
case-studies/
├── botc-2026.md # 第 1 次:血染钟楼
├── reading-notes-2026.md # 第 2 次:读书笔记(假想)
└── tech-blog-2027.md # 第 3 次:技术博客(假想)每个案例记录:
- 主题背景
- 实际花费时间
- 遇到的新坑
- 学到的新模式
3 次实践之后,方法论会自然成熟。
九、超越当前方案的优化方向
优化 1:自动化 Vercel 部署
目前 Vercel 还要手动在网页 Import 仓库。可以用 Vercel CLI:
npm i -g vercel
vercel link # 关联仓库
vercel deploy # 部署或者用 Vercel 的 GitHub App 一键开通所有仓库自动部署。
优化 2:模板生成器
写一个 new-blog-topic.sh 脚本,问几个问题(主题名、英文 slug 等),自动生成所有文件:
$ new-blog-topic.sh
主题名: 读书笔记
英文 slug: reading-notes
描述: 个人读书思考归档
✅ 已创建 ~/notes/读书笔记/
✅ 已生成所有模板
✅ 已 init git + 推 Gitee + 推 GitHub
✅ 下一步: cd ~/notes/读书笔记 && npm install优化 3:内容生成集成 AI
写个 prompt 模板,拿到一篇文章主题就让 AI 帮写第一稿,再人工修改。
总结
方法论 = 把每一次踩坑都变成下一次的捷径这套 playbook 不是为了第一次实践——第一次怎么搞都会踩坑。它是为了第二次、第三次、第 N 次——让每次新主题都比上次省一半时间。