必须用 os.RemoveAll 删除整个项目目录,因其可递归删除非空目录;但需先校验路径合法性、限定根范围并拒绝绝对路径和 ..,避免误删生产文件。

直接删项目目录,用 os.RemoveAll,但别一上来就调用——它不校验路径、不问你是不是真想删 /usr,删错就是生产事故。
删整个项目目录:必须用 os.RemoveAll,不是 os.Remove
os.Remove 只能删单个文件或空目录;对 myproject/ 这种含源码、配置、go.mod 的目录,它会立刻报 directory not empty 错误,根本删不动。
-
os.RemoveAll("./myproject")才是正确选择:递归进子目录、删所有文件和子目录,最后把myproject自身也抹掉 - 路径末尾带不带
/都行:"myproject"和"myproject/"行为一致 - 如果路径不存在,
os.RemoveAll返回nil(不报错),这点比os.Remove更“安静”
删之前不校验路径,等于裸奔
用户输入、配置项、命令行参数传来的路径,可能含 .. 或绝对路径,比如 data_dir = "../../etc"。直接拼进去删,os.RemoveAll 照删不误。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 先转成绝对路径:
abs, _ := filepath.Abs(input) - 再限定根范围:
strings.HasPrefix(abs, allowRoot),比如只允许删/tmp/myapp/下的东西 - 拒绝危险成分:
filepath.IsAbs(input) || strings.Contains(input, "..")就直接返回错误 - 测试时用临时目录:
dir, _ := os.MkdirTemp("", "test-*"); defer os.RemoveAll(dir),天然隔离
删大项目目录时,进程可能卡住几秒甚至更久
os.RemoveAll 是同步阻塞操作。删一个含上万小文件的 vendor/ 或 node_modules/ 目录,在机械盘或 NFS 上可能耗时数秒,期间无法响应 SIGINT(Ctrl+C)。
立即学习“go语言免费学习笔记(深入)”;
- 没内置中断机制,Go 运行时不会自动中止正在进行的系统调用
- 若需可中断,得自己开 goroutine +
context.WithTimeout,再配合信号监听,但底层删除仍无法真正取消——只能等它完成或超时后放弃后续逻辑 - 高频清理场景(如 CI 构建缓存),建议先
os.Chmod(path, 0755)解决只读文件权限问题,避免中途因permission denied中断
真正难的从来不是“怎么删”,而是“删之前有没有确认这是用户本意、路径是否越界、被占用的文件是否已释放”。os.RemoveAll 很快,但删错一次,恢复成本远高于加三行校验代码。

















