为什么chmod的递归模式不会执行递归操作,而是执行其他操作?

8

chmod -R 775 *.cgi 只会更改当前目录中的文件权限,子目录中的文件不会被修改。这与仅执行 chmod 775 *.cgi 的功能完全相同。我见过有人使用find等解决方案。很好,但是如果-R模式根本没有实现任何功能,那么为什么它还存在呢?


谢谢大家的回答。解释使用find命令的答案很有用,但我选择了msw的答案,因为我更好奇-R是什么意思。我之所以选择msw而不是Matthew,是因为msw的回答略早一些。 - Razor Storm
5个回答

16

可能是因为您没有命名为*.cgi的目录。引用手册中的话:

  

-R 递归更改文件模式位。对于每个命名目录的文件操作数,chmod将更改该目录和其下面的文件层次结构中的所有文件的文件模式位。

例如:

$ ls -R
.:
a  a.c  b.c  c.c

./a:
a.c  b.c  sub

./a/sub:
a.c  b.c  
$ chmod -R 444 *.c
$ ls -l
drwxr-xr-x 3 msw msw 4096 2010-08-12 18:07 a
-r--r--r-- 1 msw msw    0 2010-08-12 18:07 a.c
-r--r--r-- 1 msw msw    0 2010-08-12 18:07 b.c
-r--r--r-- 1 msw msw    0 2010-08-12 18:07 c.c
$ : directory a not affected
$ chmod -R u-w a    
$ ls -l a
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 a.c
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 b.c
dr-xr-xr-x 3 msw msw 4096 2010-08-12 18:07 sub
$ ls -l a/sub
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 a.c
-r-xr-xr-x 1 msw msw    0 2010-08-12 18:07 b.c
$ : got em

10

-R参数告诉chmod命令进入作为参数给出的任何目录。

如果你执行chmod -R 775 *.cgi,Shell会将*.cgi扩展为匹配该模式的文件列表,并将其作为参数列表传递给命令chmod。因此,命令chmod不需要查找其他目录。

(它会递归地进入与*.cgi匹配的任何目录...)


1
哦,明白了。所以它可以递归地更改某个目录下的所有文件。 - Razor Storm

7
为实现您想要的目标,请尝试:
find . -name '*.cgi' -print0 | xargs -0 chmod 755

这里的find命令会在当前目录及其子目录下生成一个.cgi结尾的文件列表,并将该列表传递给xargs命令,该命令会对每个文件应用chmod命令。


4

*.cgi会被shell扩展为当前目录中所有以.cgi结尾的文件名列表。然后shell使用这个文件名列表调用chmod

chmod查看从shell获取到的所有文件名,更改它们的模式,并且如果其中有一些是目录,则递归执行。但是很可能没有任何一个是目录,所以没有需要递归的内容。

要查找当前目录及其子目录中的所有cgi文件并对其运行chmod,可以执行以下操作:

find . -name '*.cgi' -print0 | xargs -0 chmod 775

这个答案与dmckee的一样。 - Sharique Abdullah

3

*是一个shell内置命令,而-R则是一个命令行选项。因此,chmod永远不会将*作为参数。

假设foo0.cgi和foo1.cgi是目录的内容。如果您键入chmod -R o+r *.cgi,那么chmod将得到“-R”、“o+r”、“foo0.cgi”和“foo1.cgi”作为参数。

您想要做的事情可以很容易地实现:

find . -iname '*.cgi' | xargs chmod 755

这个答案和dmckee的一样。 - Sharique Abdullah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接