os.createtemp的pattern必须含且仅含一个*作为随机占位符,否则panic;dir应显式指定可信路径并确保存在;go1.19+推荐用三参数版本指定权限,临时资源须显式安全清理。

os.CreateTemp 的 pattern 参数必须带且仅带一个 *,否则 panic
pattern 不是 glob 模式,而是唯一性占位符:Go 用随机字节替换 * 来避免命名冲突。漏写、多写或放错位置都会直接 panic。
-
os.CreateTemp("", "log-*.txt")✅ 生成/tmp/log-aB3f.txt -
os.CreateTemp("", "log.txt")❌ panic:pattern contains no asterisk -
os.CreateTemp("", "log-*.tmp.*")❌ panic:pattern contains multiple *s -
os.CreateTemp("", "subdir/*.log")❌ 不会创建子目录,而是在当前目录建一个字面名为subdir/*.log的文件
dir 参数不能传空字符串,否则可能被 TMPDIR 劫持
传 "" 会让 os.CreateTemp 调用 os.TempDir(),而该函数读取 TMPDIR 环境变量——攻击者可伪造它,把临时文件导向任意路径(比如软链到 /etc/)。
- 生产环境应显式指定可信路径,如
filepath.Join("/var/tmp", "myapp") - 提前调用
os.MkdirAll(dir, 0755)确保目录存在(Windows 下不自动创建父目录) - 容器或 CI 中
os.TempDir()可能返回只读路径,显式检查比依赖 fallback 更可靠
权限必须在创建时用第三个参数指定,别事后 chmod
默认权限是 0600(仅属主读写),安全但有时需共享读取(如日志被外部工具 tail)。错误做法是创建后再 os.Chmod(file.Name(), 0644)——中间存在竞态窗口,其他进程可能在此期间读取或篡改文件。
- Go 1.19+ 支持三参数版本:
os.CreateTemp("", "log-*.log", 0644) - 不要用
0666:Linux 下受 umask 影响不可控,0600或0644更明确 - Windows 忽略权限位,但 Go 仍尝试设置;跨平台项目建议统一用
0600或按runtime.GOOS分支处理
临时文件和目录必须显式清理,defer os.Remove 不够用
os.CreateTemp 和 os.MkdirTemp 都不自动删除资源。只靠 defer os.Remove(file.Name()) 有缺陷:如果函数提前 return、panic 发生在 defer 前、或文件需跨 goroutine 使用,就可能漏删或误删。
- 文件清理推荐:
defer func() { _ = os.Remove(file.Name()) }() - 目录清理必须用
os.RemoveAll,且应包在匿名函数里:defer func() { _ = os.RemoveAll(dir) }() - 测试中优先用
t.TempDir()+t.Cleanup(),它们自动处理 panic 和并发场景 - 绝不要
os.RemoveAll(os.TempDir()):会误删其他程序的临时文件
dir 的可控性和清理时机——尤其在容器或高并发服务中,一个未显式指定的 "" 或一个裸 defer os.Remove,可能让临时文件堆积、权限失控,甚至引发路径劫持。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











