为什么不能使用 chmod 通过八进制表示法清除 setuid/setgid/sticky 位?

dig*_*ale 5 linux chmod

今天上班时,管理层随机出现,要求我给一群工程师上一门关于使用 Linux 的速成课程。显然,他们已经听到了我与 Microsoft 的分歧(由于 Win 10 隐私和安全问题),现在我是任何事情的常驻“专家”*nix。

在向小组解释了 Linux 的简单之美之后,提出了有关文件权限的问题。我解释了chmod用于分配权限的用户组世界八进制语法。

然后是 setuid/setgid/sticky 位——我用一个简单的例子进行演示,并chmod 2755 somefile.txt指出 setgid 位现在已启用。为了清除该位,我发出chmod 0755,但令我沮丧的是 setgid 位仍然存在。什么??我知道我以前曾使用过该语法来清除粘性位(尽管可能是十年前)。当我谈论完这个设计有多么优雅之后,我发现它不起作用,这真是令人尴尬。

不管怎样,我还向他们展示了g+s替代g-s的速记法,并发现它g-s确实有效。

演示结束后,我以为我发现了一个错误chmod,但在查看man页面后,我发现该行为是“设计使然”,因为有一个明确的注释说明chmod可用于设置粘性标志,但不能清除它们。

chmod为什么使用八进制表示法清除粘性位的功能被删除了?我用谷歌搜索,发现有些人说前导零“令人困惑”,应该省略。真的吗?按照这种逻辑,我们不妨说字节(例如 ASCII 代码)包含前导“0”位是非法的,因为它“令人困惑”。觉得前导零令人困惑的人可以使用符号表示法。想要使用八进制表示法的人应该能够使用八进制。

为什么chmod不支持八进制表示法来清除粘滞位?

dir*_*rkt 3

问题是,在引入粘性位之前,已经有许多 shell 脚本等只使用了三个八进制数字(或更少)。此外,任何数字都可以用前导零填充的惯例是相当根深蒂固的。

因此,如果允许带有前导零的八进制形式重置粘性位,许多脚本会意外地重置粘性位。调试这将是一场噩梦,因此最终chmod会受到无法以八进制形式重置粘性位的限制。毕竟,如果您确实想重置它们(这种情况很少发生),您始终可以使用替代形式。

因此,就像许多令人惊讶的复杂性形式一样,答案是“向后兼容性”。