Chmod 和 -r +r

Chmod 和 -r +r

我尝试以错误的顺序调用命令 chmod。chmod file.txt -r出于某种原因,这个命令成功了。chmod file.txt +r但另一方面却无法工作。这是为什么?为什么一个命令可以工作,而另一个命令却不行?

答案1

这是 GNU chmod 处理输入的一个怪癖,并且不能移植到所有与 POSIX 兼容的 chmod 实现。

请注意POSIXchmod命令行语法需要模式首先出现,GNUchmod(选项也应该位于模式之前)。其他任何事情都是未记录的实现怪癖。


现在,让我们来看一下为什么在这个特定的实现中会发生这种情况:

这暗示了手册

不过,通常情况下,“ chmod a-w file”是更可取的,并且如果它的行为与“ ”的行为不同,则会发出抱怨chmod -w file(不带) 。--chmod a-w file

简而言之,由 解析的选项以 为getopt前缀-。与 类似ls -aa是一个选项。完整形式ls --all具有all作为选项。rm -rf(相当于rm -r -f)同时具有rf选项。

其他一切都是非选项参数,技术上称为操作数.我喜欢称这些为位置参数,因为它们的含义由它们的相对位置决定。在 中chmod,第一个位置参数是模式,第二个位置参数是文件名。

理想情况下,模式不应该以 开头-。如果是这样,你应该使用--来强制解析为操作数而不是选项(即使用chmod a-w filechmod -- -w file代替chmod -w file。这也是建议由 POSIX 提供。


如果你看看源代码,你会注意到它使用获取选项解析命令行选项。这里对“不正确”模式有特殊处理,例如-w

    case 'r':
    case 'w':
    case 'x':
    case 'X':
    case 's':
    case 't':
    case 'u':
    case 'g':
    case 'o':
    case 'a':
    case ',':
    case '+':
    case '=':
    case '0': case '1': case '2': case '3':
    case '4': case '5': case '6': case '7':
      /* Support nonportable uses like "chmod -w", but diagnose
         surprises due to umask confusion.  Even though "--", "--r",
         etc., are valid modes, there is no "case '-'" here since
         getopt_long reserves leading "--" for long options.  */

以你的例子来说:

  • chmod a-r file.txt将是最坚固调用。
  • chmod +r file.txt有效是因为第一个参数在位置上被解释为模式。
  • chmod -r file.txt仍然有效,因为-r被解释为一个简短的r选项和特殊情况。
  • chmod -- -r file.txt是正确的,并且有效,因为 被-r位置解释为模式。这与没有的情况不同,--因为--没有-r不会被解释为选项
  • chmod file.txt -r仍然有效,因为-r被解释为短r选项和特殊情况。选项不依赖于位置。这在技术上滥用了未记录的怪癖。
  • chmod file.txt +r不起作用,因为+r是操作数,而不是选项。第一个操作数 ( file.txt) 被解释为模式... 并且解析失败。

相关内容