我尝试以错误的顺序调用命令chmod。chmod file.txt -r
这出于某些原因起作用。chmod file.txt +r
另一方面拒绝工作。为什么是这样?出于什么原因一个命令起作用,而另一个则不起作用?
我尝试以错误的顺序调用命令chmod。chmod file.txt -r
这出于某些原因起作用。chmod file.txt +r
另一方面拒绝工作。为什么是这样?出于什么原因一个命令起作用,而另一个则不起作用?
Answers:
这是GNU chmod如何处理输入的古怪之处,并非可移植到所有POSIX兼容的chmod实现中。
请注意,POSIXchmod
coomand-line语法要求模式优先,GNUchmod
也是如此(选项也应该位于模式之前)。其他任何事情都是无证的实现怪癖。
现在,说明为什么它在此特定实现中发生:
在手册中有提示:
但是,通常情况下,“
chmod a-w file
”是更可取的,并且chmod -w file
(没有--
)会抱怨它的行为是否不同于“chmod a-w file
”的行为。
简而言之,由解析的选项getopt
以开头-
。像中的一样ls -a
,a
是一个选项。长形式ls --all
具有all
作为一个选项。rm -rf
(相当于rm -r -f
)同时具有r
和f
选项。
其他所有内容都是非选项参数,技术上称为操作数。我喜欢称它们为位置参数,因为它们的含义取决于它们的相对位置。在中chmod
,第一个位置参数是mode,第二个位置参数是文件名。
理想情况下,模式不应以开头-
。如果是这样,则应该使用--
强制将解析作为操作数而不是选项(即使用chmod a-w file
或chmod -- -w file
代替chmod -w file
。),POSIX 也建议这样做。
如果查看源代码,您会发现它使用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. */
以您的示例为例:
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扩展中排在第一位,则可能会产生有趣的结果。