纯文本+Shell脚本:构建极简数字工作流,告别SaaS工具绑架

📅 发布时间:2026/10/8 17:10:36
纯文本+Shell脚本:构建极简数字工作流,告别SaaS工具绑架
如果你和我一样每天在十几个在线工具之间来回切换——记笔记用一个 App、待办用一个 App、文件同步再挂一个云盘、写博客还要搭一套 CMS——那你迟早会问自己一个问题这些工具真的让我的效率变高了吗还是只是在不断制造“需要管理工具的工具”我花了很长时间才想明白这件事。最终我做了一个略带幽默的决定给这套极简工作流起名叫caveman取“穴居人”的意思。不是说要回到钻木取火的时代而是想用最原始、最少依赖的方式解决现代数字生活里那些本不该复杂的琐事。caveman 不是某个开箱即用的商业软件它是我自己的一套方法论加一组不到 200 行的 Shell 脚本核心就三条原则能离线解决的绝不联网能存纯文本的绝不用数据库能用一个命令完成的绝不用图形界面。这套东西我用了一年半从知识管理、待办事项、文件备份到博客发布全部跑在本地全部依赖一个文本目录和几个脚本。这篇文章就把完整的搭建思路、脚本实现和踩坑记录全部放出来适合那些受够了订阅制、全家桶、云锁定想重新拿回数据控制权的人参考。1. 先搞清楚caveman 到底是个什么东西很多人一听“极简工具”第一反应是“那不就是用个 Markdown 笔记软件吗”。不是。caveman 比这个更激进它连“笔记软件”都去掉了只剩一个文件夹。你觉得这是倒退我一开始也觉得但跑通之后才发现这才是真正的自由。1.1 名字的由来穴居人式的极简名字我想了很久最终敲定 caveman 是因为它很准确地描述了我想要的状态。穴居人没有复杂的工具但人家活得挺好。他们没有“生产力套件”但需要传递信息的时候在墙上画个画就够了。放到今天我觉得我们大部分人面对的数字事务也远没到需要重型工具的地步。caveman 的基本架构极其朴素一个主目录里面按用途分几个子目录数据全部是纯文本文件操作全部通过 Shell 脚本完成。它不启动任何后台服务不创建任何数据库不上传任何数据到云端。你打开终端敲一个命令完事。关掉终端什么都不会在后台偷偷跑。这套思路的灵感其实来自程序员圈子里那句老话“如果你想让某个东西活 30 年就别让它依赖一个会在 3 年后倒闭的 SaaS 服务。”纯文本文件的寿命几乎等于无限长而任何一个商业软件的寿命都是一场赌局。1.2 这套方案适合谁不适合谁我必须先把丑话说在前面caveman 不是适合所有人的它甚至不是效率最高的方案它的核心价值是自主和可控不是便捷。我整理了适合和不适合的人群供大家参考适合不适合独立开发者、程序员需要多人实时协作的团队喜欢折腾命令行的人完全不想碰终端的纯小白对数据隐私和所有权敏感的人重度依赖手机端移动办公的人文字工作者、自我管理者需要复杂表格和富文本排版的人受够了工具碎片化的极简主义玩家期望开箱即用、零学习成本的人我自己属于“能接受一定学习成本但拒绝长期被工具绑架”的类型。如果你也是后面这部分完全可以照抄。如果你不是看完理解思路也行至少在选工具的时候能多一层判断标准。2. 为什么我放弃了“全家桶”式工具链这一节聊聊decision背后的逻辑。毕竟任何放弃成熟工具链的决定都需要足够充分的理由不然就是单纯的矫情。2.1 现代工具链正在吃掉你的时间和注意力先说一个我自己的真实经历。前两年我的数字生活是这样的笔记用印象笔记待办用滴答清单随手记录用手机备忘录收藏网页用浏览器书签写博客用 WordPress存文件用百度网盘和 iCloud 双线并行。听起来很齐全对吧实际上每次我想找个东西先得想“这东西当时存在哪了”然后在五个应用里来回翻。更崩溃的是印象笔记的导出格式越来越封闭滴答清单的免费额度越来越紧百度网盘不充会员下载速度跟蜗牛一样。工具的稳定性也在下降每次 App 更新都可能改掉一个我用了很久的功能。时间久了你会发现这些工具的存在不是为了帮你省时间而是为了让你持续关注它、持续订阅它、持续在里面沉淀内容好让你离不开它。你再也没法删掉它因为你几年的笔记、几百条待办、几千个书签都在里面。这就是数字时代的斯德哥尔摩综合征。我当时做了一个数学题我对工具的真实需求其实只有四个——记录信息、记住要做的事、备份重要文件、对外输出内容。这四个需求真的需要五个 App 加三个云服务来解决吗显然不需要。于是 caveman 项目立项了。2.2 选型判断的“最少依赖”三原则决心下定之后我开始琢磨怎么判断一个方案值得不值得用总不能全凭感觉。后来我总结出三个判断原则用到今天帮我在工具选型上避开了无数大坑。第一个原则是数据所有权。数据必须是我随时能用文本编辑器打开、能复制粘贴、能带走的东西。只要数据被格式绑架在某个平台里不管它宣称多么好用我直接排除。第二个原则是单点故障概率。如果这个工具消失了我的数据会怎样如果云服务商跑路数据是否还在本地如果公司停止维护文件能否自行打开答案只要有一个是否定的这个工具就不可靠。用纯文本文件就没有这个问题——文件永远不会因为软件停运而打不开。第三个原则是迁移成本。从一个方案换到另一个方案需要花多少时间商业工具之间数据迁移往往是一场噩梦但在 caveman 体系内迁移成本几乎为零想换个方案把目录拷走就可以了任何新工具只要能读纯文本就能无缝接手。这三个原则后来也成了我判断任何一个新工具的标尺。你会发现用这套标准一过滤市面上 90% 的“生产力神器”都被淘汰了剩下的基本只剩文本文件。3. 核心实现caveman 四件套这一节是全文最实在的部分我把自己真正在用的四套脚本和目录结构完整放出来。整套东西跑在 macOS 和 Linux 上都没问题Windows 用户装个 WSL 或者 Git Bash 也能用。代码不长但每一行都有它存在的意义。3.1 纯文本知识库目录即结构搜索即索引知识管理这块我放弃“卡片”、“双链”、“图谱”这些花哨概念回归原始方案目录树加纯文本文件。没有数据库索引所谓索引就是你给文件夹起的名字本身。我的目录结构是这样设计的caveman/ ├── notes/ # 全部笔记 │ ├── projects/ # 按项目分类 │ ├── areas/ # 按领域分类 │ ├── resources/ # 收藏的资料、摘录 │ └── archive/ # 归档的旧笔记 ├── tasks/ │ ├── todo.txt # 待办事项 │ └── done.txt # 已完成归档 ├── files/ # 附件PDF、图片等 ├── scripts/ # 所有脚本 ├── backups/ # 本地备份目录 └── site/ # 静态博客输出笔记本身没有花哨的格式就是带个标题的 Markdown文件名就是文章的标题。比如一篇关于“如何做备份策略”的笔记文件名就是backup-strategy.md。有人肯定会问没有标签系统怎么找东西答案是靠搜索。我做一个别名命令直接用 ripgrep 搜索目录里的所有文本alias cavrg --smart-case --hidden -l -g !site/** -g !backups/**用的时候直接cav 关键词不到一秒所有匹配文件路都列出来。比任何笔记软件的搜索都快而且搜的是真正的全文连 PDF 里的文字都能通过-g *.txt等手段处理更复杂的提取可以交给外部脚本日常使用完全够用。这里要提一个我的实战体会笔记软件里的“分类”其实是幻觉真正实用的分类结构只要两级就够——领域加项目。不要试图建立超过三层的文件夹体系层级越深维护成本越高最后你会发现所有东西都堆在“其他”里。3.2 任务管理一个 Shell 脚本顶一个待办应用待办事项在 caveman 里就是一行一行的文本。状态用前缀标记[ ]表示未完成[x]表示已完成。任务文件todo.txt长这样[ ] 给博客换域名需要修改 DNS 记录 [ ] 整理 2025 年家庭照片选出 50 张冲印 [x] 给车做年检管理这些任务的脚本不到 30 行我挑几个关键函数讲。首先是添加任务#!/usr/bin/env bash # todo.sh极简任务管理 TODO_FILE$HOME/caveman/tasks/todo.txt DONE_FILE$HOME/caveman/tasks/done.txt add() { echo [ ] $* $TODO_FILE echo 已添加$* }完成一条任务我用行号来定位而不是任务内容避免出现内容重复导致误操作done() { if [[ $1 ~ ^[0-9]$ ]]; then sed -i ${1}s/\[ \]/[x]/ $TODO_FILE echo 任务 $1 已完成 else echo 请用编号指定任务 fi }列出当前任务就一行grep -n \[ \] $TODO_FILE给每行任务加了行号显示方便后续操作。归档已完成任务也很暴力archive() { grep \[x\] $TODO_FILE $DONE_FILE sed -i /\[x\]/d $TODO_FILE }你可能发现了脚本没有任何时间提醒功能。这是故意的因为我做过一次实测发现任务提醒并不会让我更快做完事情只会让我在收到提醒时压力变大然后再花一分钟把提醒改为“明天再说”。真正的待办管理只需要回答“现在该做什么”和“接下来有什么事”提醒功能本来就是个伪需求。如果你确实需要某个日期的提醒一条 cron 任务发个通知就解决了不用为此买一个待办 App 的会员。3.3 本地备份rsync 三行脚本搞定全量安全感数据安全是很多人最焦虑的部分。我的方案极其简单增量备份到一块本地移动硬盘再定期对拷一份到另一台机器。核心命令是 rsync。#!/usr/bin/env bash # backup.sh增量备份整个 caveman 目录到外置硬盘 BACKUP_ROOT/Volumes/BackupDisk/caveman rsync -avz --delete \ $HOME/caveman/ \ $BACKUP_ROOT/这条命令的意思是把主目录所有内容镜像到备份盘-a保持文件属性-v显示过程-z压缩--delete让备份和源目录保持一致源目录删掉的文件在备份里也会删掉。这里必须解释一个大多数人容易做错的事云端同步不等于备份。百度网盘、iCloud 这类服务它会把你本地的删操作也同步过去你不小心删了文件云端也会删。rsync 配合定时任务则不会——备份永远是源目录某个时间点的快照。我配合一条 crontab 每天自动跑0 22 * * * $HOME/caveman/scripts/backup.sh $HOME/caveman/logs/backup.log 21每天晚上十点自动备份早上起来瞄一眼日志文件大小就知道昨晚有没有备份成功。这比任何“自动云备份”都心里有底因为你知道数据具体存在哪块硬盘上哪个目录里甚至可以直接用find逐文件核对。3.4 博客输出从 Markdown 到静态页面caveman 的对外输出也走极简路线。我的博客就是这个site目录里面只有静态 HTML没有数据库没有后台没有插件。生成方式是一条脚本把notes/posts下的 Markdown 文件转成 HTML。我用的转换工具是 pandoc这也是整个项目里唯一允许的“重型依赖”。理由很现实手写一个 Markdown 解析器纯属重复造轮子pandoc 是开源工具行为稳定跨平台而且它读的是纯文本不会绑架数据。#!/usr/bin/env bash # site.sh发布博客 cd $HOME/caveman/site # 1. 用 pandoc 把每篇 Markdown 转成独立 HTML 页 for md in ../notes/posts/*.md; do name$(basename $md .md) pandoc $md -o posts/$name.html --standalone done # 2. 重新生成首页列表按文件名倒序 ls -t posts/*.html | sed s/.*\///; s/\.html$// | \ while read -r name; do echo lia href\posts/$name.html\$name/a/li index.tmp done mv index.tmp index.html echo 博客已更新共发布 $(ls posts/*.html | wc -l) 篇文章脚本简单粗暴但够用。每次写完文章把 Markdown 丢进notes/posts跑一下bash scripts/site.sh然后rsync site/ 服务器目录/就能上线。整个过程不到 10 秒不需要打开任何后台面板。这里我踩过一个坑最初版本直接用文件名排序结果10.md会排在2.md前面后来加了ls -t按修改时间排序才解决。这种细节文档里永远不会写。4. 实操记录从零搭一个 caveman 环境光讲思路不够这一节把从零搭建的完整过程过一遍包括初始化命令、脚本里容易踩的坑、以及从商业工具迁移出来的真实路径。如果你决定用这套方案照着做就行。4.1 初始化目录结构和命名规范搭建第一步不是写脚本而是确定目录结构和命名规范因为后面所有脚本都依赖这个结构改起来麻烦。我自己用了几轮之后最终固定成前面展示的那套。用三条命令初始化mkdir -p ~/caveman/{notes/{projects,areas,resources,archive},tasks,files,scripts,backups,site/logs} touch ~/caveman/tasks/todo.txt ~/caveman/tasks/done.txt命名规范我推荐两条硬性规则。第一文件名一律用小写字母加连字符不要用空格和中文比如backup-strategy.md而不是备份策略 v3 最终版.md。第二日期脱离开文件名让文件名的语义保持纯粹日期属性交给ls -l或文件系统来记录。这样脚本处理时不会因为空格和特殊字符踩坑——所有踩过文件名空格坑的人都知道我在说什么。脚本这块我把所有脚本都放在scripts/下并加进 PATH用起来直接敲todo add 写周报、cav 备份这种命令不用每次打全路径echo export PATH$HOME/caveman/scripts:$PATH ~/.zshrc4.2 写脚本最容易踩的三个坑脚本本身不难但有几个环境相关的坑新手绕不过去。我把最典型的三个列出来。第一个是文件名里有空格。如果你在 Mac 上创建了带空格的 Markdown 文件然后脚本里用了for md in ../notes/posts/*.md你以为是按文件循环实际会被拆成两个脚本直接崩。解决办法有两个从源头规范文件名推荐或者在脚本里正确加引号while IFS read -r md; do ... done (ls ...)。务实点说直接规范命名最省心。第二个是中文编码问题。macOS 的终端默认 UTF-8 没问题但 Windows 上跑 WSL 就可能遇到文件读取乱码。这个坑没有华丽的解法只有一条经验所有涉及文本处理的脚本一律在开头声明export LANGen_US.UTF-8脚本文件本身也统一存成 UTF-8 不带 BOM 的格式。第三个是 crontab 的环境变量。cron 执行脚本时PATH和你在终端里看到的是不一样的。比如你手动跑backup.sh好使挂到 crontab 里就报rsync: command not found。原因就是 cron 环境里没把 rsync 的路加进 PATH。解决方法是在脚本开头写死 rsync 的绝对路径或者统一在脚本入口把环境变量额外加载一遍。我最终的 backup.sh 开头长这样#!/usr/bin/env bash export PATH/usr/local/bin:/opt/homebrew/bin:$PATH这几行字在教程里很少被提及但少了它你的定时任务一定会出问题。4.3 从 Notion、印象笔记、滴答清单迁移的真实路径很多人想尝试这套方案卡在迁移这一步过往数据怎么办我给一条务实的路径亲身验证过。首先是印象笔记。不要想着把笔记本全部导出来然后用工具自动转换那样的结果一定是一堆乱七八糟的 HTML。我的做法是先在印象笔记里把所有笔记标题规范成“领域-主题”格式然后批量导出.enex或 HTML再用脚本按标题里的领域关键词自动分门别类丢到notes/projects和notes/areas下的不同文件。内容里如果有代码片段转成 Markdown 时注意代码块格式丢失的问题最初几周我会定期抽查手动修复格式。然后是 Notion。Notion 导出 Markdown 的功能相对靠谱但导出的附件是散落的不会自动放到对应文章目录下。处理方式也简单把导出后的 Markdown 和附件放到同一个目录脚本自动把图片路径改掉。我的一个笨办法是把所有图片统一放到files/下文件名用YYYYMMDD-index.png的方式顺便解决了 Notion 附件名混乱的问题。滴答清单更简单因为它本身支持导出纯文本或 CSV。导出后人工扫一遍把那些“明天再说”重复了两周的任务删掉剩下的按优先级和状态补上[ ]前缀丢进todo.txt就完成了。迁移那天你会发现一件神奇的事你 80% 的待办都是早该删除的垃圾这个告别仪式本身就很治愈。5. 常见问题与排查技巧实录任何方案都有自己的坑caveman 也不例外。我把这一年半遇到的高频问题整理成了一个速查表后面针对三个典型问题细讲。这是最实的部分直接能救命。问题现象解决办法cron 任务没执行日志为空脚本手动跑正常检查 cron 的 PATH、脚本权限、绝对路径中文搜索无结果rg 搜不到中文字符确认文件编码是 UTF-8不是 GBK文件越来越多乱得没法找目录结构失控清理空文件合并相似目录重建归档规则手机上打不开 Notes出门在外没有电脑自建 WebDAV / 局域网页面rsync 备份完硬盘放不下源目录膨胀太快减小备份范围排除site/和backups/5.1 cron 任务没跑先查这四件事定时任务不执行是这类方案遇到最多的故障90% 的原因集中在这四点。第一脚本没有执行权限。创建的文件默认权限是 644不会自动带x权限。检查方法很简单ls -l看文件权限对不对不对就chmod x。第二绝对路径问题。crontab 里的执行路径要写全不要写相对路径。我之前吃过一次亏写的是scripts/backup.sh结果 cron 在/目录下压根找不到这个路径白跑了两周。第三cron 的 PATH 环境变量。前面提过脚本里手动补一段export PATH是最省心方案。第四日志输出没留存。排查时看不到任何信息。这里有一个我的习惯所有 cron 任务都必须把输出写到固定日志文件命令最后接 /path/to/log 21。没有日志排错就是盲人摸象。把这四件事全查一遍99% 的定时任务问题都能解决。5.2 文件多到失控以后我这样恢复秩序caveman 初期很美好但半年后我发现自己开始往notes/areas里乱丢文件导致结构逐渐失控。偶尔还出现重复文件——同一篇摘录既放在resources又放在projects某个目录。这时候赶紧整理越拖越乱。我的恢复方案是三步。第一步用脚本找出超过 90 天没修改且内容相同的文件然后统一删除或归档。第二步把目录层级压平原则是“超过一屏的目录结构本身就是一种负担”合并相似的分类比如把notes/areas/work和notes/projects/current合并成notes/active。第三步从那时起给新笔记增加一条硬规则新笔记只能放进 5 个固定目录之一不允许新建顶层目录。三个月跑下来混乱度大幅下降。这里有个经验值可以提供对个人知识库来说超过 500 个文件的目录如果找东西开始变慢不是文件太多而是结构不对。caveman 不是数据库它不负责深度管理只负责让你快速存取。所以别贪多定期清理才是关键。5.3 手机上看不到数据怎么办“手机上看东西”是这套极简方案里最弱的一环也是很多人无法坚持使用的原因。我的方案分两层。第一层是纯只读方案我把notes目录用 rsync 同步到一台家里的小主机上装一个轻量 Web 服务比如alist或单纯的python3 -m http.server。手机浏览器打开局域网地址就能像浏览网页一样看所有笔记。够用但只支持查看不支持编辑。第二层是读写方案用 Syncthing 在手机和电脑之间同步caveman目录。Syncthing 是开源的本地同步工具不走任何第三方云端设备之间直接点对点传输。手机装个客户端选好目录就能在手机自带的文件管理器里直接改todo.txt。同步延迟基本几秒内体验接近于商业云盘但数据始终在你自己手里。如果你有顾虑不愿意自建任何服务那还有最后一道防线在任何一台电脑上操作然后用 Git 仓库记录变更。等你回到电脑前pull 一下就能拿到手机上的修改。这个方案零额外依赖代价是要稍微习惯一下 Git 的基本操作。写在最后我的真实体会跑这套 caveman 体系一年半下来最大的改变不是“效率变高了”而是“焦虑变少了”。以前我每隔几天就会担心云盘快满了、会员快到期了、某个工具又改版了现在这些统统不存在。数据就躺在我硬盘的目录里任何人任何公司都删不掉它也锁不住它。坦白说我并不是建议所有人都放弃现在的工具毕竟商业工具在协作、移动办公这些场景下确实有不可替代的优势。但如果你也时常觉得“工具在用我”那我强烈建议哪怕只做一件事——把你最重要的一百篇笔记和所有待办导出成纯文本放到本地目录里。不需要你完全迁移至少给数据留一条后路。最后分享一个小技巧这套东西跑顺以后你会不自觉地开始用同样思路看待生活里的其他选择——那些需要持续付费才能维持的东西、那些绑定你数据的东西、那些离了它你就活不了的东西都会让你本能地警惕。这种警惕是自由的开端。