我想先讲一个我写过的最没用的脚本,然后再讲我现在的判断标准。顺序反过来的话,这篇会变成又一篇「自动化改变人生」的鸡汤,而我更想讲清楚的是自动化的成本。
那个自动整理下载文件夹的脚本
四年前我写过一个脚本,每隔一小时扫描下载文件夹,按扩展名把文件分到 图片、文档、压缩包、安装包 四个子目录,超过三十天的自动移进「归档」。
写它花了我大概三小时,包括调试路径转义的问题。我当时非常满意,觉得终于治好了下载文件夹的混乱。
它带来的实际后果是:接下来一年,我每次找刚下载的文件都要多花三十秒。 因为我的肌肉记忆是打开下载文件夹按时间排序,看最上面那个。而脚本已经把它挪走了。更糟的是脚本在后台静默运行,我经常在还没意识到的时候文件就没了,然后开始怀疑自己是不是没下载成功。
更狠的一次:我下载了一个客户发来的文件,扩展名是 .dat,不在我的四个分类里,脚本把它归到了「其他」。三周后我要找它,完全不记得叫什么名字,也不记得有「其他」这个目录。花了二十分钟才翻出来。
我最后是怎么处理的?删掉脚本,改成每周五手动扫一眼下载文件夹,看到没用的就删。这个动作两分钟,一年一百分钟。而那个脚本,光是写它就三小时,加上一年里被它坑掉的时间,远超一百分钟。
我另外两次失败
为了不显得只是运气不好,再说两个:
- 自动整理笔记标签的脚本。 它会根据关键词给笔记打标签。跑了两个月后我发现,它打的标签我一个都没用过,因为我搜笔记从来是搜正文不是搜标签。这是典型的自动化了一个我根本不需要的动作。
- 自动生成周报的脚本。 从提交记录里抽取信息,拼成周报。同事很快发现我的周报每周长得一模一样,只有条目不同,读起来像机器写的——因为它就是。周报的意义在于我停下来想一想这周,而我把这个「想一想」自动化掉了。
三次失败的共同点
我事后梳理,发现它们都犯了同一类错误的不同变体:
- 自动化了一个我没有真正测量过频率的动作。(下载文件夹其实没那么乱)
- 自动化了一个不该被消灭的动作。(写周报时的思考)
- 自动化的产物没人消费。(那些标签)
我现在动手前问三个问题
问题一:我真的做了多少次?
不许估计,要数。我的办法是先把这个动作手动做两周,每次做完在一个文件里记一行。两周后看行数。有好几次我以为「天天在做」的事,两周只发生了三次。
粗略的门槛是:手动总耗时要能在半年内覆盖掉开发加维护的成本。 而维护成本我一律按开发成本的两倍估——这个系数是我用血教训换来的。
问题二:它失败的时候,我会知道吗?
这是我现在最看重的一条。一个静默失败的自动化比没有自动化危险得多,因为它会让我停止检查。
我的备份脚本跑了半年,我以为一切正常。有一次我随手看了眼备份目录,发现最后一次成功是四个月前——磁盘满了,脚本报错了,但错误输出到了一个没人看的地方。四个月的东西如果那时候丢了,我就完了。
现在我所有的自动化都必须有一个我看得见的输出。备份脚本会在我的每日文件里追加一行时间戳;同步脚本失败时会直接改我的终端提示符颜色。丑,但我一定会注意到。
问题三:半年后我还看得懂吗?
我给自己定了个规矩:超过五十行的自动化脚本,必须在开头写清楚它解决什么问题、什么情况下应该删掉它。 第二句比第一句重要。写不出退出条件的脚本,说明我没想清楚。
现在活着的四个自动化
都很笨,但都活了两年以上:
- 每天凌晨的备份,带可见的成功标记。
- 一个把当前剪贴板里的链接加上日期存进稍后读文件的快捷键。三行。
- 项目初始化脚本,建目录、初始化版本库、拷一份配置模板。
- 一个批量转换图片尺寸的命令别名。一行。
四个里有两个不到十行。我发现存活率和复杂度是反相关的——那些我写得最精巧、最有工程感的自动化,全都死了。活下来的都是丑陋的、显而易见的、五分钟就能重写一遍的东西。
自动化的真正价值不在于省时间,在于把某个动作从「需要决定」变成「不需要决定」。而这件事,简单的方案往往做得更好。