"Sticky bit" 仅适用于目录?我发现它可能在文件上,很奇怪
"Sticky bit" is only for directories? I found it could be on files, weird
来自网站的样本说 "sticky bit" 用于目录,例如
$ ll /tmp
drwxrwxrwt 16 root root 4096 1月 2 15:45 ./
我们可以看到/tmp的执行权限是"t",任何人都可以执行,但是某些目录只有"root"或者它的所有者才能操作。
所以我之前的理解是,这个文件权限标志只针对目录,不针对文件。但是,当我使用 "open" 函数创建文件时,我 运行 遇到了这个问题,我没有指定任何文件权限作为第三个参数,所以我的程序是:
#include<fcntl.h>
#include<unistd.h>
int main()
{
int f1=open("./mytest_c1.txt",O_CREAT|O_RDWR);
write(f1,"abc xyz\n",8);
close(f1);
return 0;
}
执行后得到了这样一个文件:
--wxr-x--T 1 x x 8 1月 2 11:38 mytest_c1.txt*
奇怪,这里是大写 "T"。
- 我是如何生成这个 "T" 标志的?我没有指定任何内容。
- 和小写有什么区别"t"?
所以我继续我的实验,我删除了"write"语句,即:
#include<fcntl.h>
#include<unistd.h>
int main()
{
int f1=open("./mytest_c2.txt",O_CREAT|O_RDWR);
close(f1);
return 0;
}
运行 结果创建了另一个文件:
-rw---x--T 1 x x 0 1月 2 15:59 mytest_c2.txt*
这一次,更奇怪了。 mytest_c2.txt 的文件权限不同于 mytest_c1.txt.
这种差异从何而来?我没有在程序中指定任何内容!
区别:表示粘性位,在 t
版本中设置了执行位,在 T
中未设置执行位。
原因:Linux从父目录继承权限(如果对目录设置ACL,则只有该目录内的文件继承ACL。如果创建子目录,则不会除非 ACL 设置为递归,否则不会获取父 ACL) 因此在这种情况下,文件所在的文件夹...对于该粘滞位已设置。这就是为什么新创建的文件会继承它。
For my case ACL is set to recurse. For OP's case too that is set to
recurse otherwise it won't inherit parent's the ACL of parent.
这是不正确的:
int f1=open("./mytest_c1.txt",O_CREAT|O_RDWR);
这条语句invokes undefined behavior (UB). Whenever you use open(2)
with flags that include O_CREAT
, you must (as stated in the manpages)指定文件模式。您看到的粘性位是由于 UB 导致意外发生的结果。
现在,还有其他一些有趣的观点:
We can see the execution permission of /tmp is "t", everyone can execute, but certain directories can be operated only by either "root" or its owner.
这并没有错误,但有点误导。更准确地说,如果目录有粘性位(例如 /tmp
通常有),这意味着任何人都可以 在该目录中创建 文件,但是 只有所有者(和 root
,因为 root
几乎可以做任何事情)可以在创建文件后修改或排除该文件。
下一个:
The samples from web sites says "sticky bit" is for directories, e.g.
另外,也没有错,只是有点误导。粘滞位 can be applied to files,但 Linux 会忽略它们。
来自网站的样本说 "sticky bit" 用于目录,例如
$ ll /tmp
drwxrwxrwt 16 root root 4096 1月 2 15:45 ./
我们可以看到/tmp的执行权限是"t",任何人都可以执行,但是某些目录只有"root"或者它的所有者才能操作。
所以我之前的理解是,这个文件权限标志只针对目录,不针对文件。但是,当我使用 "open" 函数创建文件时,我 运行 遇到了这个问题,我没有指定任何文件权限作为第三个参数,所以我的程序是:
#include<fcntl.h>
#include<unistd.h>
int main()
{
int f1=open("./mytest_c1.txt",O_CREAT|O_RDWR);
write(f1,"abc xyz\n",8);
close(f1);
return 0;
}
执行后得到了这样一个文件:
--wxr-x--T 1 x x 8 1月 2 11:38 mytest_c1.txt*
奇怪,这里是大写 "T"。
- 我是如何生成这个 "T" 标志的?我没有指定任何内容。
- 和小写有什么区别"t"?
所以我继续我的实验,我删除了"write"语句,即:
#include<fcntl.h>
#include<unistd.h>
int main()
{
int f1=open("./mytest_c2.txt",O_CREAT|O_RDWR);
close(f1);
return 0;
}
运行 结果创建了另一个文件:
-rw---x--T 1 x x 0 1月 2 15:59 mytest_c2.txt*
这一次,更奇怪了。 mytest_c2.txt 的文件权限不同于 mytest_c1.txt.
这种差异从何而来?我没有在程序中指定任何内容!
区别:表示粘性位,在 t
版本中设置了执行位,在 T
中未设置执行位。
原因:Linux从父目录继承权限(如果对目录设置ACL,则只有该目录内的文件继承ACL。如果创建子目录,则不会除非 ACL 设置为递归,否则不会获取父 ACL) 因此在这种情况下,文件所在的文件夹...对于该粘滞位已设置。这就是为什么新创建的文件会继承它。
For my case ACL is set to recurse. For OP's case too that is set to recurse otherwise it won't inherit parent's the ACL of parent.
这是不正确的:
int f1=open("./mytest_c1.txt",O_CREAT|O_RDWR);
这条语句invokes undefined behavior (UB). Whenever you use open(2)
with flags that include O_CREAT
, you must (as stated in the manpages)指定文件模式。您看到的粘性位是由于 UB 导致意外发生的结果。
现在,还有其他一些有趣的观点:
We can see the execution permission of /tmp is "t", everyone can execute, but certain directories can be operated only by either "root" or its owner.
这并没有错误,但有点误导。更准确地说,如果目录有粘性位(例如 /tmp
通常有),这意味着任何人都可以 在该目录中创建 文件,但是 只有所有者(和 root
,因为 root
几乎可以做任何事情)可以在创建文件后修改或排除该文件。
下一个:
The samples from web sites says "sticky bit" is for directories, e.g.
另外,也没有错,只是有点误导。粘滞位 can be applied to files,但 Linux 会忽略它们。