os.chmod权限值必须是八进制字面量(如0644),不可用十进制数(如644),否则会因进制误解析导致权限错乱;windows下仅影响只读位,其余无效。

os.Chmod 传入的权限值必须是八进制字面量
Go 中文件权限不是十进制数,0644 和 644 完全不同:0644 是八进制(对应 Unix 权限 rw-r--r--),而 644 是十进制,会被解释为八进制 1204,结果不可控甚至破坏性。常见错误就是漏写前导 0。
实际可用的典型权限值包括:
-
0600:仅所有者可读写(密钥、token 文件首选) -
0644:所有者可读写,组和其他人只读(配置、文档) -
0755:所有者可读写执行,组和其他人可读执行(脚本、二进制) -
0444:所有人只读(设只读时比0644更安全)
用位运算动态调整权限,而不是覆盖重设
直接 os.Chmod(path, 0444) 会抹掉原有执行位、特殊位等,有时你只想关掉写权限、保留读和执行——这时该用位运算。
curr &^ 0222 是标准做法:&^ 表示“清零指定比特”,0222 正好是所有用户写权限位(-w--w--w-)。例如:
fi, err := os.Stat("data.bin")
if err != nil {
log.Fatal(err)
}
curr := fi.Mode().Perm()
newPerm := curr &^ 0222 // 仅移除写位
err = os.Chmod("data.bin", newPerm)
注意:0222 必须带前导 0;若误写成 222,结果是十进制 222 → 八进制 336,会清错位。
Windows 上 os.Chmod 几乎只影响只读标志
Windows 不支持 POSIX 权限模型。os.Chmod 在 Windows 下仅尝试设置或清除 os.ModeReadOnly 对应的文件属性(即资源管理器里的“只读”勾选框),其他位(如执行、组权限)被忽略。
这意味着:
-
os.Chmod(path, 0400)或0600→ 设为只读 -
os.Chmod(path, 0644)→ 清除只读(变为可读写) -
0755中的x位无任何效果,不会让文件变可执行
跨平台程序若依赖权限位做逻辑判断(比如“是否可执行”),在 Windows 上必然失效,必须由应用层兜底。
创建文件时就设权限,别靠 os.Chmod 补救
先写内容再调 os.Chmod 存在时间窗口:敏感数据(如密钥)可能被其他进程在权限变更前读取。更安全的做法是在创建/写入瞬间就定死权限。
推荐方式:
-
os.WriteFile("token.txt", data, 0600):一步到位,原子性强 -
os.OpenFile("log.txt", os.O_CREATE|os.O_APPEND, 0644):日志类文件常用 -
os.Mkdir("secrets", 0700):目录需注意x位代表“可遍历”,不是“可执行”
特别注意:os.MkdirAll 只保证最后一级目录按给定权限创建,上级目录默认用 0755,如有强一致性要求,得手动逐级 os.Mkdir 并校验。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











