go语言os.FileMode函数如何转换整数/八进制/ ???的权限在设置标志之前?

时间:2018-01-06 01:50:42

标签: unix go chmod

更新:基于到目前为止的评论和回复,我想我应该明确表示我理解0700是十进制数448的八进制表示。我关注的是当八进制时模式参数或当十进制数重新转换为八进制并传递给os.FileMode方法时,使用WriteFile创建的文件的结果权限似乎排列在有意义的方式。

我尽我所能努力将问题的大小缩小到它的本质,也许我需要通过另一轮的那个

Update2:在重新阅读之后,我想我可以更简洁地陈述我的问题。调用os.FileMode(700)应该与使用二进制值1-010-111-100调用它相同。有了这9个最低有效位,应该有以下权限:

--w-rwxr--或274八进制(并转换回

相反,该FileMode导致WriteFile创建文件:

--w-r-xr--八进制为254。

使用go中编写的内部实用程序时,在使用ioutil.WriteFile()创建文件时,使用decimal 700而不是octal 0700会导致文件创建权限错误。那是: ioutil.WriteFile("decimal.txt", "filecontents", 700) <- wrong! ioutil.WriteFile("octal.txt", "filecontents", 0700) <- correct!

当使用十进制数字(即没有前导零来将其标识为go_lang的八进制数)时,应该具有权限的文件 0700 -> '-rwx------'0254 -> '--w-r-xr--'

修复之后,我注意到当我将700十进制转换为八进制时,我获得了“1274”而不是&#34; 0254&#34;的实验结果。

当我将700十进制转换为二进制时,我得到:1-010-111-100(我添加了破折号,其中rwx是分开的)。这看起来像是&#34; 0274&#34;除了正在设置的前导位。

我去查看the go docs for FileMode并看到了封面下的FileMode是一个uint32。九个最小的位映射到标准的unix文件perm结构。前12位表示特殊文件功能。我认为第十位中的一位领先位置处于未利用区域。

我仍然感到困惑,所以我试过了:

package main
import (
    "io/ioutil"
    "fmt"
    "os"
)

func main() {
    content := []byte("temporary file's content")
    modes := map[string]os.FileMode{
        "700": os.FileMode(700),
        "0700": os.FileMode(0700),
        "1274": os.FileMode(1274),
        "01274": os.FileMode(01274)}
    for name, mode := range modes {
        if err := ioutil.WriteFile(name, content, mode); err != nil {
            fmt.Println("error creating ", name, " as ", mode)
        }
        if fi, err := os.Lstat(name); err == nil {
            mode := fi.Mode()
            fmt.Println("file\t", name, "\thas ", mode.String())
        }
    }
}

现在我更加困惑了。我得到的结果是:

file     700    has  --w-r-xr--
file     0700   has  -rwx------
file     1274   has  --wxr-x---
file     01274  has  --w-r-xr--

并通过查看文件系统确认:

--w-r-xr--     1 rfagen  staff           24 Jan  5 17:43 700
-rwx------     1 rfagen  staff           24 Jan  5 17:43 0700
--wxr-x---     1 rfagen  staff           24 Jan  5 17:43 1274
--w-r-xr--     1 rfagen  staff           24 Jan  5 17:43 01274
  • 第一个是在内部应用程序中触发原始错误的破碎情况。
  • 第二个是更正后的代码按预期工作。
  • 第三个是奇怪的,因为1274十进制似乎转化为0350
  • 第四种是扭曲的一种感觉,假设dec(700) - &gt; oct(1274)并明确要求01274给出与第一种情况相同的令人费解的0254。

我有一种模糊的怀疑,即大于2 ^ 9的数字的额外部分在某​​种程度上弄乱了它,但即使在查看the source for FileMode之后我也无法弄明白。据我所知,它只能看到12 MSB和9 LSB。

2 个答案:

答案 0 :(得分:2)

os.FileMode只知道整数,它并不关心文字表示是否是八进制。

基础8中解释0700的事实来自language spec本身:

  

整数文字是表示整数的数字序列   不变。可选前缀设置非十进制基数:0表示八进制,0x   或十六进制为0X。在十六进制文字中,字母a-f和A-F   代表值10到15。

这是编程语言中representing literal octal numbers的一种相当标准的方式。

答案 1 :(得分:1)

因此,您的文件模式已从请求的0274更改为实际的磁盘0254。我敢打赌,您的umask是0022。在我看来,一切正常。