我正在使用此命令递归地设置文件的权限
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 文件被更改。