我试图更好地理解权限,所以我正在做一些“练习”。这是我在各自输出中使用的一系列命令:
$ umask
0022
$ touch file1
$ ls -l file1
-rw-r--r-- 1 user group 0 Mar 16 12:55 file1
$ mkdir dir1
$ ls -ld dir1
drwxr-xr-x 2 user group 4096 Mar 16 12:55 dir1
这是有道理的,因为我们知道默认文件权限是666
( rw-rw-rw-
),目录默认权限是777
( rwxrwxrwx
)。如果我从这些默认权限中减去 umask 值,我对
666-022=644
, rw-r--r--
, file1
,所以它与之前的输出一致;
777-022=755
, rwx-r-x-r-x
, 对于dir1
, 也是连贯的。
但是,如果我将 umask 从更改022
为021
,则不再存在。
这是该文件的示例:
$ umask 0021
$ touch file2
$ ls -l file2
-rw-r--rw- user group 0 Mar 16 13:33 file2
-rw-r--rw-
是646
,但应该是666-021=645
。所以按照前面的计算是行不通的。
这是目录的示例:
$ touch dir2
$ ls -ld dir2
drwxr-xrw- 2 user group 4096 Mar 16 13:35 dir2
drwxr-xrw-
是756
, 777-021=756
. 所以在这种情况下,结果与之前的计算是一致的。
我读过这个人,但我没有发现任何关于这种行为的信息。
有人可以解释为什么吗?
解释
正如答案中所指出的:umask
' 的值不会从数学上从默认目录和文件的权限中减去。
有效涉及的操作是 AND (&) 和 NOT (!) 布尔运算符的组合。鉴于:
R = 结果权限
D = 默认权限
U = 当前 umask
R = D & !U
例如:
666& !0053 = 110 110 110 & !000 101 011 110 110 110 & 111 010 100 = 110 010 100 = 624 = rw--wr--
777& !0022 = 111 111 111 & !000 010 010 111 111 111 & 111 101 101 = 111 101 101 = 755 = rwxr--xr-x
小费
快速了解生成的权限(至少对我有帮助)的一种简单方法是认为我们只能使用 3 个十进制值:
r = 100 = 4
w = 010 = 2
x = 001 = 1
权限将是这 3 个值的组合。
" "
用于表示未给予相对权限。
666 = 4+2+" " 4+2+" " 4+2+" " = rw rw rw
因此,如果我当前的 umask 是0053
我知道我正在从组中删除读取和执行(4+1)
权限,并(2+1)
从其他组中删除写入和执行权限,则会导致
4+2 " "+2+" " 4+" "+" " = 624 = rw--w-r--
(组和其他已经没有执行权限)
umask
是一个掩码,它不是一个减去的值。因此:想想所涉及的部分。模式中的 6 表示第 1 位和第 2 位被设置、读取和写入。掩码中的 2 掩码位 1,即写位。掩码中的 1 掩码位 0,即执行位。
另一种表示这一点的方法是查看文本形式的权限。666 是
rw-rw-rw-
;022 是----w--w-
; 021 是----w---x
。掩码从模式中删除其设置位,因此rw-rw-rw-
被变为掩蔽,由----w--w-
变为rw-r--r--
掩蔽。----w---x
rw-r--rw-
你需要用二进制而不是十进制来思考。具体来说,有三个 3 位二进制数:所有者、组和其他各一个。每个值的范围从 000 到 111(十进制的 0-7)。
例如 rw-rw-rw (666) 是 110 110 110。
该
umask
值是一个掩码,指定在创建新文件或目录时哪些位将打开或关闭(1 或 0)。例如 022 十进制是 000 010 010 二进制,而 021 十进制是 000 010 001许可位与取反的 umask 一起进行 AND 运算以得出最终值。“否定”意味着所有位都被反转,即所有 1 都翻转为 0,反之亦然。例如
NOT 022 (000 010 010) = 755 (111 101 101)
示例:
666 & !022 = 644
。在二进制中,即:另外,
777 & !022 = 755
:请注意,如果在原始权限值(666 或 777)和取反的 umask中每个位的最终值都为 1,则每个位的最终值只能为 1 。如果其中任何一个为 0,则结果为 0。即1 & 1 = 1,而1 & 0 = 0。
严格来说,setuid、setgid 和sticky 位有第四个3 位二进制数。这就是为什么您经常看到使用前导 0(或 0-7 中的其他一些前导数字)指定的权限和掩码。例如 0777 或 2755。