寻找 。 .[^.]* -type f -print0 | xargs -0 sudo chmod 664;不起作用

寻找 。 .[^.]* -type f -print0 | xargs -0 sudo chmod 664;不起作用

我正在使用此命令递归地设置文件的权限

clime@vm6879 /srv/www-php/steeltrading $ find . .[^.]* -type f -print0 | xargs -0 sudo chmod 664

但执行该命令后,某些文件(大多数)的权限仍然没有改变。

clime@vm6879 /srv/www-php/steeltrading $ ll media/xmlconnect/system/ok.gif 
-rwxrwxr-x. 1 www www 295 Jul  5  2012 media/xmlconnect/system/ok.gif

如果我运行只是find为了查看该文件是否在列表中,我可以看到它:

clime@vm6879 /srv/www-php/steeltrading $ find . .[^.]* -type f | grep ok.gif
./media/xmlconnect/custom/ok.gif
./media/xmlconnect/original/ok.gif
./media/xmlconnect/system/ok.gif

如果我进入目录 media 并再次运行命令,该文件最终会获得正确的权限。

clime@vm6879 /srv/www-php/steeltrading $ cd media/
clime@vm6879 /srv/www-php/steeltrading/media $ find . .[^.]* -type f -print0 | xargs -0 sudo chmod 664
clime@vm6879 /srv/www-php/steeltrading/media $ ll xmlconnect/system/ok.gif 
-rw-rw-r--. 1 www www 295 Jul  5  2012 xmlconnect/system/ok.gif

看起来sudo chmod 664某些文件没有执行,这似乎是xargs问题所在,但很奇怪(没有错误消息)。请问知道可能是什么原因吗?

编辑:或者也许管道大量数据可能是一个问题?

答案1

find不会跳过点文件,因此.[^.]*.[!.]*在标准语法中)是多余的,并且会导致这些文件被处理两次(目录被降序两次)。 (另请注意,例如.[!.]*会错过调用的文件..foo)。

但是,find默认情况下,不会下降到目录的符号链接。因此,如果media是指向外部区域的符号链接.,则该区域中的文件将不会被处理。

您可以使用-L告诉 find 遵循符号链接。但请注意,它也会导致chmod调用作为常规文件的符号链接的文件。

sudo find -L . -type f -exec chmod 664 {} +

或者使用一些find/xargs实现:

find -L . -type f -print0 | sudo xargs -r0 chmod 664

与这里所说的相反,xargs如果参数列表太大,find -exec +将负责分割参数列表。chmod

但应该注意的是,我们在这里讨论的限制是传递给命令(系统execve(2)调用)的参数和环境的累积大小。

find并将xargs确保未达到该限制(并留出一点余量),但如果您将其运行为:

find . -type f -print0 | xargs -r0 sudo chmod 644

代替:

find . -type f -print0 | sudo xargs -r0 chmod 644

sudo命令(由 调用xargs)将接收要传递到的所有参数chmod,并且还会再次传递一个包含文件列表SUDO_COMMAND的环境变量chmod,因此它将大约是传递到的 arg+env 大小的两倍chmod,并会解释为什么限制被超过。

答案2

您传递给的参数字符串可能chmod太长。您在这里有几个选择。

使用 find 的 exec 选项

当与分号一起使用时,find 的 exec 选项将针对找到的每个文件运行一次命令:find . .[^.]* -type f -exec sudo chmod 664 -- '{}' \;

使用 xargs 限制参数数量

xargs -n5每个命令实例最多传递五个参数。您还可以使用该-s标志来限制传递给命令的字符数:xargs -s4096。您可以增加限制以获得更好的性能;只是要小心不要走高。

递归 chmod

chmod有一个递归选项。但这会影响目录和文件。如果您担心取消设置目录上的执行位,可以在运行第一个命令后运行chmod -R +X(注意大写X)以递归设置目录的执行位。

答案3

我不明白你想对目录名 .[^.]* 做什么(我认为这是多余的)并且我认为你不需要 -print0 -0 选项,我怀疑你在某处遇到缓冲区溢出管道或命令行大小

尝试

find . -f file  -xargs chmod {}\;

您可以在 chmod 上使用 -v 来查看 ech 文件被更改。

相关内容