工具大全
Claude 指南作者:Coocon2026年8月19日366 次阅读约 11 分钟阅读

Claude 没有写那个打印机驱动:14KB 胶水代码、一个 Linux 容器,和 HP 自己的二进制

Claude 没有写那个打印机驱动:14KB 胶水代码、一个 Linux 容器,和 HP 自己的二进制

8 月 17 日,19 岁的开发者 Kuber Mehta 发了一条推:

"just Claude writing a MacOS driver for my obscure HP printer built only for Windows support"

两天时间,262 万阅读、14805 个赞。作者当时只有两千多粉丝,这是一次彻底的自然爆发。Hacker News 上开了两个帖子(151 分和 105 分),媒体也跟进了,wccftech 的标题更进一步,写成了 "Wrote A Driver For macOS From Scratch"。

我把仓库拉下来看了一眼。代码构成是这样的:

语言 字节数
Shell 6,497
Python 7,638
Dockerfile 550

总共约 14KB,没有一行 C,没有编译型 filter,没有内核代码。

而 README 里作者自己写着:

"This repo contains only glue code. It does not redistribute HP's driver. install.sh downloads the Unified Linux Driver from HP at install time."

真正把页面数据编码成打印机能懂的格式的,是 HP 官方 Linux 驱动里的 rastertospl 二进制——被放进 Mac 上的一个 Linux 容器里跑。

所以标题不成立。但如果文章到这里就结束,那才是真的看漏了:这四个小时里发生的事情,比「写了个驱动」这个假命题有意思得多,而且它精确地画出了今天 AI 干脏活的能力边界在哪。


一、这台打印机为什么在 macOS 上是块砖

HP Laser 1008a 属于 HP Laser 1000 系列。关键背景:这是 HP 2017 年收购三星打印机业务之后的换标三星机型,血统不是 LaserJet。

它带来三个后果:

  1. 说的是 SPL/QPDL 语言(三星那一系的页面描述语言),不是 PCL,也不是 PostScript。README 里那行表格写得很直白:Generic PCL / PostScript → "Printer speaks neither, so the CUPS backend hangs 'offline'"。
  2. 是 host-based 打印机——机器里没有解释器,光栅化得在主机端做完再传过去。俗称「傻瓜打印机」。
  3. HP 从来没出过 macOS 驱动,Linux 侧的官方方案是三星血统的 ULD(Unified Linux Driver),最新一版发布于 2020 年。

开源社区那边也没有现成答案。这一点很重要,我逐个核过:

项目 支持 1008a 吗
hplip 不支持。Launchpad 上的官方答复:「The HP Laser 100 series is not supported by HPLIP」——这个系列是三星血统,走 ULD 不走 hplip
foo2zjs 协议就不对。它支持的 HP LaserJet 1000/1005/1018/1020 是老的 ZjStream 系,和「HP Laser」(没有 Jet)1008a 是两码事
splix 名义上支持,实测失败。splix 2.0.2 通过 PR #9 加了 "HP Laser 10x" 支持,但该 PR 原文自己写着 "HP are not tested";而且它面向的是 HP Laser 103-108 那条线,1008a 属于另一条产品线,SPL3 帧格式有差异

所以这不是一个「翻翻 GitHub 就有」的问题。这台在亚马逊上正常售卖的打印机(HN 用户 1970-01-01 专门吐槽过 "obscure" 这个形容:「Obscure? Sir, the printer is sold on Amazon.」),在 Mac 上确实是块砖。

二、四个小时里真正发生了什么

作者把完整的 Claude Code 会话记录(209KB Markdown)公开了,这是这件事最有价值的部分——它让整个过程可复核。

起点是一句极其随意的 prompt:

"hey can you set up the drivers for HP Laser 1008a on this mac please, it's connected"

然后是一条长长的失败链:

  1. Generic PCL PPD → 队列卡死在 "offline-report connecting-to-device"
  2. 搜索确认是三星血统的 SPL 机型,试 splix-macos(ML-2010 PPD) → 打印机固件被之前灌进去的 PCL 垃圾数据搞挂了,STATUS:BUSY,需要用户物理断电重启
  3. 查 USB 描述符,发现接口的 bInterfaceProtocol = 4,即 IPP-over-USB——这解释了 macOS 自带 usb backend 为什么一直误判 offline
  4. 绕行方案:用 pyusb/libusb 直写 USB bulk endpoint。先撞上 macOS 内核驱动占用(EACCES),确认只有 root 能 detach
  5. 首次直写 QPDL:出纸了,但内容是乱码,而且连吐 4-5 张。用户的原话是 "it printed... something LOL back to back 4-5 times",还附了照片
  6. 试 raw PWG/URF 直写 → 被打印机静默吞掉;试 IPP-over-USB 通道 → HTTP 通了但 /ipp/print 返回 404
  7. 试 foo2qpdl -z0 → 打印机自己打出一张错误页:"SPL ERROR - Please use the proper driver";试 1200x600 分辨率 → 又打出一张:"SPL ERROR Illegal Resolution ... ERROR CODE: 11-1113"

第 7 步这里有一句话,我认为是整份记录里最漂亮的技术观察,来自 Claude:

"the printer's error page is basically telling us how to fix it each time."

打印机每次都在用打印出来的纸告诉你哪儿错了。 把厂商固件的错误报告当成调试通道用——这是很老派、很对的工程直觉。

三、转折点不是 Claude 想到的

走到这一步,方向仍然是错的:还在试图用开源实现凑出一个能被打印机接受的 SPL3 编码器。splix 的 600dpi A4 波段宽度表都调对了(608 字节),输出还是「页面原点处的条纹光栅,反复出纸」。

决定性的一步来自用户。 他建议:别再逆向了。

Claude 的回应,原文:

"Oh, that's a much better instinct than reimplementing — we don't need to reverse-engineer or clean-room anything. The actual SPL3 codec is freely downloadable."

于是从 ftp.hp.com 下载 ULD 压缩包,打开一看——里面有 aarch64 版本的 rastertospl,能在 Apple Silicon 上的 Linux 容器里原生跑。

第一张干净的测试页就是这么打出来的。

我想把这一段单独拎出来,因为它是全文最有信息量的地方:

在「怎么试」上,Claude 表现得很强。 它读懂了 USB 描述符、认出了 IPP-over-USB 协议号、诊断出 backend 误判的根因、想到了 libusb 直写、发现了只有 root 能 detach 内核驱动、把打印机的错误页当成反馈信号来迭代。这些都是需要真本事的活,而且它连续做对了。

但在「要不要试」上,它一头扎进了七步弯路。 因为初始 prompt 说的是「装驱动」,它就一路朝着「造一个能用的编码器」走,从没停下来问一句:这个编码器是不是根本不需要造,HP 官网上就摆着?

这个失败模式非常典型。模型极其擅长在你划定的方向里穷举,但不擅长质疑方向本身。 那句「别逆向了」值多少钱?它抵掉了前面所有的努力,并且是这个项目唯一真正解决问题的决策。

Matthew Garrett(mjg59,内核和固件领域的知名工程师)在 HN 上给了一个我觉得最准确的表述:

"My experience is that they're better than me at a lot of the process... so having some skills that are pretty much 'This smells wrong' helps a lot"

流程上它比你强,「这里味道不对」的嗅觉还得你自己有。

四、最终方案长什么样,以及它绕过了什么

最后落地的架构是这样的:

任意 App 按 Cmd-P
  → CUPS 队列(用 HP 官方 PPD)
  → CUPS raster
  → CUPS 自带的 socket backend(socket://127.0.0.1:9108)
  → root LaunchDaemon(Python 脚本,跑在沙箱外)
  → HP rastertospl(在 colima Linux 容器里,输出真正的 SPL3)
  → libusb 直写打印机的 USB bulk endpoint

这里面确实有真东西。macOS 的 CUPS 有强制沙箱,禁止 filter 和 backend 调用容器或直接操作 USB。绕过的方法是:不写 filter,改用 CUPS 自带的 socket backend 把数据发到 localhost 一个端口,端口那头是一个跑在沙箱外的 root 守护进程,由它去调容器转码、再用 libusb 写 USB。

等于自建了一个 backend 替代品,同时绕开了 macOS 自带 usb backend 的 offline 误判和 CUPS 的沙箱限制。这个设计是这个项目里最像工程的部分。

代价也很实在:

  • 必须常驻一个 colima Linux VM(重启后第一次打印最多等约 1 分钟,等 VM 起来)
  • 一个 root LaunchDaemon 在执行用户目录 ~/.hp1008 下的代码——HN 用户 Tiberium 专门点了这条:"It also requires a root launcher that runs code from the user ~/.hp1008 dir, so security is weakened."
  • 换个 USB PID 就得手改 direct_write.py
  • 只在 macOS 26 / Apple Silicon 上验证过

效果方面:600dpi、A4、干净的单页文本测试页,转码加写入约 1 秒。作者提供了照片。但要注意,全部实物证据都是作者单方提供的,我没有找到任何第三方复现报告。

五、HN 怎么拆的,以及作者怎么回应的

两个帖子下面,质疑相当集中:

ssdspoimdsjvv:「If I understand correctly, it just wraps an existing Linux driver in a container. You can hardly call that writing a driver.」

Tiberium(在两个帖子里都发了):「Unfortunately this is a very misleading post... Claude didn't write a driver. It basically used HP's existing proprietary driver in a Linux VM on macOS, and just bridged that to macOS.」

asveikau:「It didn't write a driver. It used a linux driver. You don't need an LLM.」

3129476 还翻出了前人工作:「Claude did not write any macOS driver. It uses the HP Linux driver inside docker. Here is prior art from 2017...」——2017 年就有人写过「在 Docker 容器里跑 Linux 打印驱动」的教程。另一位 HN 用户 oneplane 指出已经有现成产品在做同一件事(printervention.app,在浏览器 WebUSB 里跑 Linux VM 驱动打印机)。

也有中间派。mariuolo 的评价大概是最公道的一句:「But it's not completely native, it's a wrapper around the original linux driver... Still better than nothing.」happyPersonR 甚至说他更喜欢这个方案:"Makes it so if there's an issue I don't get a kernel panic."

作者的应对值得一提。 他没有硬扛:

  • 发帖后补测了 splix 2.0.2,更新 README,commit 信息写着 "Correct SpliX claim + apply review fixes"
  • 措辞从「写驱动」往回收(HN 用户 feintruled 注意到了这一点:"I note the claim on this page is walked back from the original 'writing the driver'")
  • 在 README 里公开求助:「If you can pin down the exact byte-level difference between HP's rastertospl output and SpliX's for this printer... SpliX could likely be patched and colima dropped entirely.」
  • 仓库唯一那个 issue(#1 "SpliX support"),正是 splix PR #9 的作者 ValdikSS 开的

一个 19 岁开发者,一条推爆到 262 万阅读,然后老老实实回收措辞、补做实验、开源全部会话记录供人核查——这个处理方式比那条推本身更值得夸。

他在 HN 上自己总结方法论时说的也很实在:「there's not really a hack for it, you just work with it, convey thoughts decently and try out things with educated guesses until it sticks」。

六、我的解读

第一,「AI 写了个 X」这类标题,先做一次层级折算。 通用做法是三步:拉仓库看代码构成(语言分布和字节数最诚实)、找 README 里的依赖声明、搜一遍这个领域有没有现成的开源/厂商实现。这次三步都指向同一个答案,五分钟就能查完。作者本人的 README 其实第一句就写了 "only glue code"——夸张发生在推文标题和媒体转载里,不在代码仓库里。

第二,AI 在这类任务里省掉的是「试」的成本,不是「想」的成本。 拆开看,四小时里 Claude 做对的事有个共同点:都是在明确方向下的高强度试错和信息检索——查 USB 描述符、认协议号、写 libusb 直写、读错误页迭代、绕沙箱设计。这些活人类也会做,只是要花几天而不是几小时。而它没做对的那一件——「这个轮子根本不用造」——恰恰是最省事的那个念头。方向性的怀疑,目前仍然是人的活。

第三,别急着照着装。 这个方案要常驻一台 Linux VM,要一个 root 守护进程去执行你 home 目录下的脚本,只在一种硬件和一个 macOS 版本上验证过,且没有任何第三方复现。它是一份很好的技术记录,不是一个可以推荐给别人的产品。作者自己都在 README 里请人帮忙把 colima 干掉。

第四,真正可迁移的是那句「打印机的错误页在告诉你怎么修」。 硬件和厂商固件通常会吐出比你想象中多得多的诊断信息——错误页、状态码、描述符、日志。把这些接进 AI 的反馈回路,比让它凭空「逆向」有效得多。HN 那条讨论串里几个成功案例(有人用 Claude + ILSpy + Wireshark 逆向高尔夫球车电控,有人 5 小时搞定 Xbox 手柄适配,有人做 epaper 的嵌入式 Rust 驱动)都是同一个模式:给它一个能反复读到真实反馈的闭环,而不是给它一个纯猜的任务。

那条推的标题是错的。但底下那 209KB 的会话记录,是我最近读到的关于「AI 到底能替你干哪部分脏活」的最好材料——恰恰因为它把七步弯路和那个人类给出的转折点都原样留在了里面。


参考链接

相关文章

Clash Verge 开了 TUN 虚拟网卡反而上不了网:Hysteria2 流量绕回 TUN 自己,Tailscale 又把 DNS 截走了

macOS 上的 Clash Verge Rev 2.5.6,系统代理模式一切正常,一打开 TUN(虚拟网卡)就连百度都打不开。直接连 mihomo 内核的 API 排查,发现是两个独立的根因叠在一起:一是 Hysteria2 节点的 UDP 出站没有绑定到物理网卡,被 TUN 路由吸回自己,形成回环;二是系统 DNS 被 Tailscale MagicDNS(100.100.100.100)接管,查询走 Tailscale 的 utun,Clash 的 dns-hijack 拦不到,拿回来的是被污染的 IP。修法只需两段 Merge 覆写:route-exclude-address 把节点 IP 排除出 TUN,再打开 sniffer 从 SNI 还原域名。文中每一步都附复现命令和实测输出。

故障排查tailscale+7
pitfalls2026年10月4日6 min
15
Claude Code MCP 显示 Connected 却 0 个工具:Invalid result for tools/list(ttlMs / cacheScope)实测与修法

Claude Code MCP 显示 Connected 却 0 个工具:Invalid result for tools/list(ttlMs / cacheScope)实测与修法

MCP server 显示已连接、工具数却是 0,日志里是 Invalid result for tools/list,ttlMs 与 cacheScope 校验失败。用自写 stub 在 Claude Code 2.1.280 / 2.1.285 / 2.1.288 上复现:根因不是「多了未知字段被严格校验拒掉」,而是 server 协商到 MCP 2026-07-28 后漏了这一版的必填字段(resultType、ttlMs、cacheScope),多加未知字段反而能正常通过。stdio 是否走新协议由一个默认关闭的远程开关决定,所以同一个版本有人中招、有人没事;2.1.280 打开协商后同样失败。用户侧设 MCP_PROTOCOL_NEGOTIATION=legacy(settings.json 的 env 也行)立即恢复,server 侧补上三个字段即可。

mcpclaude-code+4
pitfalls2026年10月3日7 min
18
网友拿果蝇大脑干了什么?马里奥、我的世界、DOOM……9 个项目逐个拆,复测了 2 个

网友拿果蝇大脑干了什么?马里奥、我的世界、DOOM……9 个项目逐个拆,复测了 2 个

果蝇连接组公开以后,GitHub 上冒出一批「果蝇大脑玩游戏」项目:DOOM、马里奥、Flappy Bird、我的世界、鸿蒙手机、桌面宠物,还有拿它预测股票的。我把 9 个项目的 README 逐个读完,问三个问题:用了多少个神经元、动作到底是谁决定的、有没有做过对照。答案差别很大——从 16.6 万个神经元全量跑,到 21 个神经元、权重手调。我复测了其中两个:DesktopFly 三套自带测试全过;Fly Mario 切断巨纤维后 1.7 秒掉坑,权重整体缩放到 0.8 倍就一步也不走、放大到 1.3 倍就中途摔死。顺带查清了各项目「突触数」相差 20 倍的原因。

开源github+7
fruit-fly2026年10月3日11 min
16
Claude Code 安装失败实测:npm EACCES、镜像卡 600 秒、Node 20 静默装旧版、install.sh 返回地区拦截页、原生安装器顺手卸掉 npm 版——15 条报错原文与解法

Claude Code 安装失败实测:npm EACCES、镜像卡 600 秒、Node 20 静默装旧版、install.sh 返回地区拦截页、原生安装器顺手卸掉 npm 版——15 条报错原文与解法

在 macOS 上把 claude code 安装的失败面逐个真实复现,共 15 条报错原文,全部带墙钟和 exit code。npm 全局装到 /usr/local:EACCES,exit 243。cache 目录只是 0555,npm 却报 root-owned 并建议 sudo chown。本机 npmmirror 两次分别用了 147 秒、超过 600 秒,官方源两次都在 11–12 秒(仅 2 个样本)。Node 20 不钉版本号会静默装到 2.1.197,没有任何警告。境内直连 claude.ai/install.sh 时 curl exit 0,拿到的却是一张 447KB 的地区拦截页 HTML。原生安装器会调用 npm uninstall -g,把已有的 npm 版删掉,终端里不提示——本次实测真的删掉了本机的全局安装。

claude-codenodejs+6
pitfalls2026年9月29日11 min
131