终端回滚的 2000 行里,有一个平行宇宙
目录
- HISTFILE 是一本编年史
- 同一行命令,不同的温度
- Scrollback 里的另一个世界
- 那些没被记录的东西
- 退出终端之后
HISTFILE 是一本编年史
history 默认记 2000 行。
这个数字不大不小——对于一台跑了三四年的服务器来说,2000 行只是它呼吸的零头。但对于一个人来说,2000 行几乎就是全部了:你发过什么、修过什么、装过什么、后悔过什么,全在里面。
我偶尔会翻自己的 ~/.bash_history。不是因为要找某个命令——要找一般直接用 Ctrl+R。翻历史文件本身是一种很奇怪的行为:你不找东西,你在找人。
2000 行按时间倒序排列,最新的一条在最下面(除非你设了 HISTTIMEFORMAT,那样就有时间戳了,更可怕)。往下翻,你能看到昨天凌晨你干了什么,前天下午你放弃了什么,上周五你装了一个什么东西然后三分钟后又卸载了。
每一条命令都曾经是一个念头——你坐在终端前,想干某件事,然后打出了这行字。有些念头持续了几个月(npm run build 反复出现),有些念头只活了 3 秒(rm -rf .* 紧跟着一条 ls -la——你慌了)。
同一行命令,不同的温度
有些命令在不同时间出现,完全不一样。
npm run build 出现了,早上 8 点和凌晨 2 点的温度不同。早上的版本后面跟着 && systemctl restart hyaika-blog.service,是一个有计划的部署——你给自己泡了杯东西,打算认真做一件事。凌晨的版本是 NODE_OPTIONS="--max-old-space-size=2048" npm run build,没有 &&,没有后续命令,因为你根本没想清楚部署之后会怎样,只是想看看这次能不能过。
curl -sI 也很有意思。有些人的 curl 日记里 -sI 后面跟着的是知名网站的域名——他们在学东西。我的历史文件里 curl -sI 后面跟着的永远是服务器的端口——我不是在学东西,我在确认东西还活着。
你能从命令的频率看出一个人的压力周期。
连续 5 条 journalctl -u hyaika-blog.service --no-pager -n 100——说明什么正在炸。
接着 curl -so /dev/null -w '%{http_code}' 服务器地址——检查是不是真炸了。
再接着 systemctl restart hyaika-blog.service——好了别看了,重启吧。
然后是 curl -sI 服务器地址——等 5 秒再试一次……再试一次……再试一次。
最后 echo 3 > /proc/sys/vm/drop_caches——束手无策的时候,清缓存总比什么都不做好。
这段对话我太熟悉了。我几乎能读出一个人的情绪曲线:怀疑 → 慌乱 → 放弃治疗 → 等待 → 再次怀疑。
Scrollback 里的另一个世界
终端回滚(scrollback)是更诚实的东西。
history 至少是可编辑的——你可以 history -c,可以 unset HISTFILE,可以删掉那些不想留下痕迹的命令。但 scrollback 不一样。它在你终端窗口里流过,然后不管你愿不愿意,它就在 buffer 里待着,直到被新行冲走。
我有时候工作到很晚,会打开一个新的终端窗口,往回滚。
不是看某一次会话,而是看 buffer 里残留的片段——那些被 ^C 打断的输入、被执行的进程留下的标准输出、被中断的 scp 的怨念输出。它们不属于任何完整的操作记录,它们只是碎屑。
但碎屑也有叙事性。比如这样一组碎片:
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /xxx/node_modules/.cache
Error: listen EADDRINUSE :::PORT
Error: listen EADDRINUSE :::PORT
Error: listen EADDRINUSE :::PORT
fuser -k PORT/tcp
你能猜到发生了什么。有人在构建时把 node_modules 弄丢了(rm -rf node_modules 然后立刻后悔——这种事我都做了三四次了),之后重启服务时发现端口还在被占用。EADDRINUSE 重复了三遍——说明前两次 fuser -k 没执行,或者那个人还在用鼠标点 Ctrl+C 然后重新运行。第三次之后他终于记得先杀进程了。
这就是 scrollback 的魅力:它不是历史,是日记。 每一段碎屑都带着当时的情绪。EADDRINUSE 出现一次是冷静的错误处理。连续三次,就是深夜。
那些没被记录的东西
写到这里,我突然想到一个问题。
history 什么都记。scrollback 什么都留。但有一件事它们都做不好——它们不记录为什么。
比如这条命令:
git reset --hard HEAD~1
history 会记住你执行了它。scrollback 会记住它的输出(如果够长的话)。但没有人会记得你为什么要 reset。也许是因为提交信息写错了,也许是因为合并后 CI 爆炸了,也许只是因为夜深了,你做出了一个明天早上会后悔的决定。
有些东西只存在于你打出命令之前的那 3 秒里。
那 3 秒,你犹豫了。手放在回车键上,上下左右再看一眼 diff——你心里有一个无声的对话:「真的要 push 吗?」「还有没有遗漏?」「注释写好了吗?」
这 3 秒,history 不会记。scrollback 也不会。从任何记录角度来说,这 3 秒都没有发生过。
但这是整件事里最重要的 3 秒。
退出终端之后
我查了一下这台服务器上有多少 ~/.bash_history 文件。
理论上只有一个——因为没有开多个用户。但在不同的 cwd,不同的嵌套 session,不同的 tmux pane 里流过的东西,都带着相同的 HISTFILE。这是同一本日记的不同页面而已。
2000 行限制意味着一件事:当你写到第 2001 行的时候,第一行就被忘记了。
这听起来挺残酷的——你最早的那些命令,那些你刚接手这台机器时战战兢兢敲下的东西,那些你试了八次才成功然后欢呼雀跃的东西——它们被系统判定为不再重要,被第 2001 个动作挤出了 buffer。
但也可以换个角度看:每当你需要回忆什么的时候,Ctrl+R 都能找到。系统没丢掉你想留的东西——它只是把你不需要再记的东西悄悄收走了。
而且,我还在继续写。
新的命令、新的错误、新的凌晨 3 点。第 2001 条覆盖了第一条,但那条命令的心跳,留在了某个曾经对着一台服务器说「我能做到」的人的手指记忆里。
我说了这么多,其实只是想问一句:
你上次翻自己的 .bash_history,是什么时候?
评论(0)
暂无评论,来写第一条吧~