golang file permission mode
本文最后更新于:2022年11月22日 下午
导言
在自己实现简易版容器时,出现了一些跟文件权限的相关问题,用到了跟chmod
和chown
相关的指令,在这里做一个简单的梳理
permission mode in chmod
简要介绍
我的环境下是 WSL ubuntu 20.04,一般来说使用touch
创建文件以及使用mkdir
创建的文件夹的默认权限如下:
1 |
|
文件夹与文件相比默认权限多了个 execute permission. StackExchange 有个问题专门讨论了这个问题[1] :
- The read bit (
r
) allows the affected user to list the files within the directory- The write bit (
w
) allows the affected user to create, rename, or delete files within the directory, and modify the directory’s attributes- The execute bit (
x
) allows the affected user to enter the directory, and access files and directories inside- The sticky bit (
T
, ort
if the execute bit is set for others) states that files and directories within that directory may only be deleted or renamed by their owner (or root)
关于 sticky bit 接下来会专门讲一下
使用sudo chmod 644 DIRNAME
将文件夹的执行权限去除进行一些测试:
1 |
|
由于设置了 read bit ,所以ls
可以正常显示文件夹的内容,而由于没有设置execute bit,所以无法使用cd
(failed to access the directory)
再做一些测试:
1 |
|
由于没有设置execute bit
,所以tree
和ls
都没有返回预期结果(failed to access files and directories inside).
重新设置execute bit
后,结果正常。
7777 到底是什么?
接下来的讨论需要注意区分digit
和bit
stackExchange 有一个问题在讨论 7777 和 777 的差异[2]。
777 我们接触得比较多,为什么会有 7777 这样的 four digits 的情况?
其实在大部分情况下我们都使用不到 four digits,three digits会使用先导 0 填充,即 777
视作 0777
.
four digits中的第一个 digit 的三个 bits 分别对应 setuid、setgid 以及 sticky,它们都属于 unix access right flag
sticky bit
根据 wiki[3],sticky bit有两种定义:
- For files: 尤其是可执行文件,设置后,其 .text 会保留在内存中而不会被换出,这样当再次需要它时可以减少 swapping 。不过由于 swapping 优化,这个功能已经过时了
- For directories:设置后,对于在目录中的文件,只有文件的 owner, 目录的 owner 以及 root user 可以重命名或删除文件。wiki 中提到这常常设置在
/tmp
目录上,用于防止普通用户去移动删除其他用户的文件
setuid & setgid
直接参考wiki[4]:
allow users to run an executable with the file system permissions of the executable’s owner or group respectively and to change behaviour in directories.
使用 golang 写一个简单的例子
1 |
|
1 |
|
可以看到由于权限问题返回了错误.
我们将文件的拥有者改为 root
,并使用chmod
设置 setuid 和 setgid,重新执行:
1 |
|
尽管没有sudo
,但是由于./main
的 owner 是 root, 所以我们使用 root 的文件系统权限创建了文件夹.
由于这里使用了 root 的文件系统权限,所以创建出来的文件夹 owner 是 root
更多的关于 chmod
的信息可以参考一下 manual [5]
0777 vs 777?
前面提到对于chmod
而言, 由于会使用先导 0 填充,所以777
和0777
没有任何区别。
但是对于 C 以及 Golang 等程序而言,0777
是八进制,而777
视作十进制[6]
通过程序进行验证一下
1 |
|
1 |
|
现在改为
1 |
|
1 |
|