Notes · 2025.10.18

macOS 没有 timeout

coreutils 没带。

2 min · tools · mac

macOS 自带没有 timeout。GNU coreutils 那一套命令,我在 Linux 服务器上随手就敲,回到这台笔记本就失败。失败还不算糟,糟的是脚本写了 timeout 30s some-command,报 command not found,我以为是后面那个命令没装。排查方向错半小时,是常事。半小时还算短。我有一次把「命令不存在」理解成「模型推理卡死」,去改 FastAPI。接口没坏,坏的是外壳那一层根本没跑起来。改错层的补丁会留下,留下就变成下一轮的谜。谜的起点是没探测二进制。

每次假设 Linux 命令都在

我在 agent 约定里写过这条,因为每次假设 Linux 命令都在,都会浪费一截时间。timeout、rg、cat -A,这三件是高频。前两个经常没有,第三个在 BSD cat 上根本不是那个意思。

检测接口要防模型推理卡死。我在 Linux 上用 timeout 包一层,本地复现时脚本直接停。当时我以为是 Python 环境坏了,重装了一次依赖。依赖没问题,是外壳命令不存在。从那以后,依赖任何二进制之前先探测。不要猜环境里装了什么。

探测很土:command -v timeout,没有就换路。不要在报错后再装一堆工具「补齐 Linux」。这台机器不是服务器。把它补成服务器,下次换实验室机器又是另一套缺口。

gtimeout,或者后台加 kill

要限时,我用两个办法。装了 GNU coreutils 的话,命令名是 gtimeout。没装就自己后台跑,记 pid,到点 kill。第二种难看,不依赖额外包,课设演示前我更愿意用难看的。

难看的写法大概是:把命令丢到后台,sleep 一段,看进程还在不在,在就杀掉,并给一个非零退出。细节我每次都要查,所以没有把它写进仓库的正式脚本。仓库脚本如果必须限时,用 Python 自己的超时,或者语言运行时提供的机制。外壳层的 timeout,我只当本机手搓。

FastAPI 那层推理超时,和外壳 timeout 不是一件事。接口超时是功能:评委换一组样本,不能只转圈。外壳超时是保护我的终端不被一个挂掉的下载占住。两件事我都叫超时,写文档时要分开。混在一句里,后来的自己会改错层。

有一次演示前,下载权重的命令没有上限。代理偶发卡住,进度条不动。我以为网断了,重启代理。其实进程还在等。如果当时有 gtimeout 或后台 kill,五分钟就能换镜像。没有,我就盯着进度条看到心里发虚。

和 rg、find 是同一类问题

rg 也经常没有。没有就 find . -maxdepth 1 -type f -print。文件列表这一层,不值得为了少打几个字去装工具。agent 若默认调用 rg,在这台机器上会先失败,再编一套「仓库是空的」的结论。结论一旦编出来,它可能去初始化一个新项目。这个后果比命令不存在严重。

所以约定里这几条是捆在一起的:没有 timeout 用 gtimeout 或后台加 kill;没有 rg 用 find;BSD cat 没有 -A,看不可见字符用 cat -v。它们都是「不要用我熟悉的 Linux 脑补这台 Mac」。

实验室那台 Ubuntu 上,这些命令大多在。我在那边写的脚本,拷回笔记本就要改。拷的时候我容易只改路径,不改命令。于是 bug 表现为「同一份脚本两台机器行为不同」。不同的原因不在业务,在外壳。

写进约定,仍会忘

约定写了不等于手不会滑。我自己敲命令时,仍会先打 timeout。打完看到 not found,才想起这篇笔记。agent 更会滑,因为它的训练分布里 Linux 更多。所以这条对 agent 比对人更硬:二进制先探测,失败就停,不要改业务代码来「绕过超时命令缺失」。

绕过的典型样子是:把限时逻辑删掉,让命令一直跑。跑通了,像修好了。演示那天模型推理超过评委耐心,接口一直转。修的是命令缺失,拆的是产品行为。我不允许这种修好。

这篇不教你装 coreutils

有人会说:brew install coreutils 不就有 gtimeout 了。可以装。我装过。装完要记的是命令带 g 前缀,且别的机器没有。个人站、检测代码、智链前端,不能把 gtimeout 写进大家要跑的脚本。

收到的限制是:本机手搓可以用 gtimeout;仓库入口用语言自己的超时。探测失败时,报「这条命令在这台机器上不存在」,不要报「网络有问题」或「模型坏了」。说错原因,后面全是废动作。

我还把这条和代理 7890 放在同一张检查单上。新终端、新会话,先看代理变量,再看 timeout / rg 在不在。两头都空的时候,下载会挂、搜索会谎报仓库是空的、限时脚本会直接 not found。谎报比慢更坏。慢我能等。谎报会让人改错文件。改错文件再回滚,答辩前那一晚就没了。所以探测要写在动手改业务之前,不要写在事故报告里当反思。