chmod 和 -r +r

Tes*_*nux 13 bash ubuntu

我曾尝试以错误的顺序调用命令 chmod。chmod file.txt -r这出于某种原因起作用。chmod file.txt +r另一方面拒绝工作。为什么是这样?出于什么原因,一个命令有效,而另一个无效?

Bob*_*Bob 18

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

请注意,POSIXchmod coomand-line 语法要求mode 首先出现,GNUchmod也是如此(选项也应该在 mode 之前)。其他任何事情都是未记录的实现怪癖。


现在,为什么它会发生在这个特定的实现中:

它在手册中暗示:

但是,通常情况下, ' chmod a-w file' 更可取,并且chmod -w file(没有--)会抱怨它的行为与 ' chmod a-w file' 所做的不同。

简而言之,被解析的选项以getopt为前缀-。像 in ls -aa是一个选项。长格式ls --allall作为一个选项。rm -rf(相当于rm -r -f)同时具有rf选项。

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

最佳情况下,模式不应以-. 如果是这样,您应该使用--强制解析为操作数而不是选项(即使用chmod a-w filechmod -- -w file代替。POSIXchmod -w file建议这样做。


如果您查看源代码,您会注意到它使用getopt来解析命令行选项。在这里,有对“不正确”模式的特殊处理,例如-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.  */
Run Code Online (Sandbox Code Playgroud)

以你的例子为例:

  • 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) 被解释为模式 ... 并且无法解析。

  • 如果您有一个名为“a+rwx”的文件并执行类似“chmod * +r”的操作,并且“a+rwx”文件恰好出现在 glob 扩展中,那么这可能会产生有趣的结果。 (4认同)