问题是这样的:我在代码里面调用了 os.Chmod("test.txt", 777)
,希望把该文件的读写及执行权限对所有用户开放。
执行完代码,顺手 ls 看了下。如下:
$ ls -l test.txt -r----x--x 1 cyhone 1085706827 0 Jun 20 13:27 test.txt
结果出乎意料,不仅文件权限没有按预期的变成 rwxrwxrwx
。反而执行完后,当前用户就只剩可读权限了,其他用户就只有可执行权限同时无读写权限。
因为这实在是一个简单又愚蠢的错误,所以先直接给出结论:
- 在 C 语言和 Go 语言中,如果想要将文件权限形式修改为
rwxrwxrwx
,需要写成0777
,而非777
。 - 0777 是八进制格式,777 是十进制格式。在用 Go 语言表示此类权限的时候,如果要对标
chmod
命令的表示形式,用八进制表示更方便和准确点。 - 如果不是在代码里,而是在命令行直接调 chmod 的话,那
0777
和777
都可以。
这个问题虽然非常简单,但尴尬的是我还踩了坑,所以把这个问题及原因分享出来。
原因
为什么 rwxrwxrwx
对应的是八进制的 0777
,而不是 777
呢?。
原因是,底层在将数字翻译成对应权限时,实际上用的该数字对应的二进制位,并将后 9 位逐位翻译。
例如,对应八进制 0777
来说,其二进制的表示如下:
从上图来看,0777
就代表了 rwxrwxrwx
。
而对于十进制的 777
,其二进制的表示形式如下:
从其按位翻译来看,恰好 777
的后 9 位,就代表了 r----x--x
, 和我们的运行结果一致。
那么话说回来,根据这个理论,如果非要用十进制表示 rwxrwxrwx
,那么应该是 511
。
我们可以用代码实验下:
fileMode := os.FileMode(511) fmt.Println(fileMode.String()) // -rwxrwxrwx
从结果看的确是符合预期的。
参考