
简介
今天刷到一篇讲 Finger 协议的文章(Finger: the 1971 social network that never died,en.andros.dev 的 Andros Fenollosa 写的),才知道原来 1971 年就有社交网络了,而且我的 Mac 上一直自带它的客户端。文章里提到的 happynetbox.com 是个把 Finger 协议做成了社交网络的网站,我注册了个账号,还写了个脚本让本地 ~/.plan 文件自动同步上去,每天早上再让 AI 翻译更新内容推给我。这篇记录下整个过程和踩的坑。
Finger 是什么
Finger 是 1971 年斯坦福 SAIL 实验室搞出来的协议。那时候想看谁在线,只能用一个叫 WHO 的命令,输出一大串很难读。有个工程师叫 Les Earnest,经常看到同事用手指在屏幕上划着找人的名字,就写了个程序,能直接查某个用户的信息:真名、位置、上次登录时间、有没有未读邮件。
后来 1977 年出了 RFC 742,1991 年定型成 RFC 1288。它干的事很简单:客户端连上对方主机的 79 端口,发一行用户名,服务器把这个人存在家目录 .plan 文件里的内容吐回来。
.plan 就是你的个人主页。那时候程序员的习惯是在里面写自己最近在干啥,John Carmack 当年就是用 .plan 当开发日记,1997 年宣布要开源 Doom 源码就是通过 .plan 发的。所以 Finger 也被叫做第一个社交网络、第一个微博。
我的 Mac 上居然还自带 finger 命令:
$ finger bboysoul
Login Name TTY Idle Login Time Office Phone
bboysoul Bboy Soul console 23:07 Wed 11:07
Happynetbox 是什么
Happynetbox(https://happynetbox.com)是 Ben Brown 做的一个实验性网站,它就是一个公开的 finger 服务器。注册个账号,写点文字,别人就能用 finger 你的名字@happynetbox.com 在终端里看到你的内容。
没有点赞、没有关注、没有 feed、没有 archive。你在网页上写一段话,然后告诉朋友 “finger 一下我”,完事。站主原话:“会有人看到吗?只有真正爱你的人才会。”
我试了下:
$ finger [email protected]
# MONDAY
We went down to HOUSTON this weekend to see the ASTROS play...
站长居然在 happy box 里写日记,讲他全家去看棒球、还有一条跑了好几周才跑通的 CI pipeline。太有味道了。
注册和登录
注册很简单,网页上填个 handle 和密码就行。我的 handle 是 bboysoul。
登录是个标准 POST 表单,handle + password 提交到 /login,成功返回 302。curl 就能搞定:
$ curl -c ~/.happynetbox.cookie -X POST https://happynetbox.com/login \
-d "handle=bboysoul&password=xxx"
cookie 存下来,有效期大概 9 天。
发现发帖接口
npm 上有个官方 CLI 叫 happynet,但它只能读(订阅列表、看更新),不能发帖。我翻了源码,它就是往 79 端口发用户名拿内容,根本没写功能。
发帖还是得走网页。看了下登录后的页面,发现 https://happynetbox.com/post/<handle> 是个编辑页,一个 textarea 加一个提交按钮,POST 过去带 content 字段就行:
$ curl -b ~/.happynetbox.cookie -X POST https://happynetbox.com/post/bboysoul \
--data-urlencode "content=Myblog: https://www.bboy.app"
返回 302 带 updated=true,就成功了。
自动化同步 .plan
既然发帖就是个 POST,那本地写个脚本就能把 ~/.plan 的内容同步上去。
我写了个脚本 happynetbox_plan_sync.sh,逻辑:
- 检查 cookie 还在不在(访问编辑页看返回 200 还是 302)
- 不在就自动用存好的密码重新登录
- 算
~/.plan的 md5,和上次同步的缓存比 - 没变就静默退出,变了就 POST 上去
然后挂了个 cron,每 30 分钟跑一次:
0,30 * * * * bash ~/.hermes/scripts/happynetbox_plan_sync.sh
这样我改 ~/.plan 文件,最多 30 分钟,全世界 finger 我就能看到新内容了。Finger 协议的玩法就该是这样——改一个本地文件,别人终端里看得到。
每天早上翻译更新
光同步还不够,happynetbox 上还有别人在更新内容。我写了个采集脚本,finger 一下 @happynetbox.com 拿到最近更新的 25 个 handle,然后逐个 finger 拿内容,输出成固定格式。
再挂个 cron,每天早上 6 点跑,内容有变化就让 AI 翻译成中文推给我。用的是 monitor 模式:脚本输出哈希对比,没变化就完全静默(0 token),谁更新了才翻谁。
这样谁更新了 happy box,我早上起来就能看到翻译版。复古协议配上现代 AI,还挺有意思的。
踩的坑
坑 1:finger 服务端不支持中文
第一次我把 .plan 写成了中文,web 端显示正常,但 finger 一查就乱码:
$ finger [email protected]
finger: reading from network: Illegal byte sequence
[happynetbox.com]
Myblog: https://www.bboy.app
@*
用 nc 直接连 79 端口看原始字节,发现服务器把 UTF-8 中文按错误编码输出了,字节流里混进一堆乱码。这是 happynetbox 服务端的 bug,1971 年的协议本来就只认 ASCII。
解决方案:.plan 里只写英文。脚本里也加了个检查,检测到非 ASCII 字符就直接报错拒绝同步:
if LC_ALL=C grep -q '[^ -~]' "$PLAN_FILE"; then
echo "⚠️ 包含非 ASCII 字符,请改成纯英文"
exit 1
fi
坑 2:nc 请求要带 CRLF
直接 echo "bboysoul" | nc happynetbox.com 79 返回 “Nobody lives here”,因为 echo 默认只发 \n,finger 协议要求 \r\n 结尾:
printf "bboysoul\r\n" | nc happynetbox.com 79
坑 3:cookie 会过期
cookie 有效期大概 9 天,过期后发帖接口会 302 到登录页。所以脚本里要加 cookie 有效性检查 + 自动重登逻辑,不然同步任务会悄悄失效。
现在的效果
我的 happy box 现在是:
Myblog: https://www.bboy.app
DevOps @ Ningbo, China.
Love open source, self-hosting, blogging and bodyweight fitness.
Feel free to finger me!
想看的话:
$ finger [email protected]
欢迎关注我的博客 www.bboy.app
Have Fun
