air 命令不生效的根源是未在 go.mod 所在目录运行,且默认仅监听 .go 文件;需正确配置 .air.toml 的 watch.include_ext、build.bin 与 build.cmd 路径,并确保构建无语法或 import cycle 错误。

air 命令不生效?先确认你在哪运行的
绝大多数“改了代码没重启”问题,根源是 air 没监控到你编辑的文件——它只从当前工作目录开始递归监听,默认不进 vendor、.git、tmp,也不自动识别子模块路径。
- 必须在
go.mod所在目录运行air,不是main.go目录,也不是 IDE 里随便点开的任意子文件夹 - 如果项目结构是
cmd/myapp/main.go,但go.mod在上层,就别 cd 进cmd/myapp再跑air,否则它根本找不到模块依赖 -
air -c .air.toml时,配置文件路径必须写对;若.air.toml在父目录,而你在子目录执行,air会静默读错配置甚至 fallback 到默认行为
改了 config.yaml 或 template.html 不重启?缺的是 watch 扩展名
air 默认只监听 .go 文件,这不是 bug,是设计定位:它专注 Go 代码热重载,不是全栈 Live Reload。模板、配置、静态资源变更不触发重启,得手动加后缀。
- 在
.air.toml的[watch]或[build]段里补上include_ext = ["go", "yaml", "yml", "html", "tmpl"] - 注意:Linux 下 inotify 句柄有限(默认 8192),加太多后缀可能报
inotify limit reached;非必要不加.log、.md这类无关后缀 - Windows 用户要额外加
.exe后缀到bin字段,比如bin = "./tmp/main.exe",否则fork/exec会失败
build-errors.log 里全是 undefined: xxx?别怪 air,先看编译本身
air 只是调度器,真正编译失败是 Go 工具链的事。看到 failed to build, error: exit status 2 别急着调配置,90% 是代码语法或 import cycle 问题。
- 打开
build-errors.log(如果你配了),或直接扫终端最后一屏红色输出——重点看是不是import cycle not allowed或undefined: handlerFunc -
build.cmd别写成go run main.go:它不复用构建缓存,每次都是冷编译,慢且绕过bin路径控制 - 推荐写法:
cmd = "go build -o ./tmp/main . && chmod +x ./tmp/main",尤其在 NFS 或某些容器环境,避免permission denied
进程杀不干净、pkill -f 'tmp/main' 成日常?配置比暴力更稳
air: failed to kill process: no such process 表面是信号发丢了,实际常因 panic 后子进程僵死,或 Windows 杀毒软件拦截 SIGINT。
- 在
.air.toml加kill_delay = "2s",给旧进程留出 graceful shutdown 时间 - Linux/macOS 下确保
tmp/目录有写权限;macOS 若用 Homebrew 装过旧版air,先brew uninstall air,否则air -v显示新版但实际跑老二进制 - 不要把
build.bin和build.cmd输出路径搞错,比如cmd写./tmp/main却把bin写成main,就会报exec: "./tmp/main": file does not exist
最易被忽略的点:热重载重启的是整个进程,HTTP server 的连接、数据库连接池、全局状态全重置——它不等价于运行时热更新,逻辑改完还得人工验证状态一致性。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











