将权限复制到Linux / Unix上的同一棵树


22

我有一个具有正确权限的文件树。那么我有一个(文件方式)相同的树(具有不同的文件内容,很难)具有错误的权限。

如何将权限布局从一棵树转移到另一棵树?

Answers:


8

可以使用以下shell行完成此操作:

D1=foo; D2=foo2; for entry in $(find $D1  -exec stat -f "%N:%Mp%Lp" {} \;); do $(echo $entry | sed 's#'$D1'#'$D2'#' | awk -F: '{printf ("chmod %s %s\n", $2, $1)}') ; done

只需为D1和D2变量设置正确的值,将它们指向源目录和目标目录,然后运行,目录将具有同步权限。


1
这假定存在统计信息。遗憾的是,我发现命令状态通常不存在。

@David,我不知道这样的系统缺少统计信息。但是使用以下“八进制ls”版本并相应地适应给定的解决方案是很简单的:alias ols =“ ls -la | awk'{k = 0; for(i = 0; i <= 8; i ++)k + =((substr(\ $ 1,i + 2,1)〜/ [rwx] /)* 2 ^(8-i)); if(k)printf(\“%0o \”,k); print}' “
drAlberT

当涉及的任何路径包含任何种类的特殊字符(空格,以破折号开头等)时中断。
n.st

31

我刚刚学习了一种新的简单方法来完成此任务:

getfacl -R /path/to/source > /root/perms.acl

这将生成具有所有权限和所有权的列表。

然后转到目标上方的一个级别并使用

setfacl --restore=/root/perms.acl

您必须处于较高级别的原因是perms.acl中的所有路径都是相对的。

应该以root身份完成。


这是备份和还原权限的非常简单明了的方法。但是,这种注意getfaclsetfacl不一定存在于所有系统。
the-wabbit

.ac在第一个命令.acl中包含第二个命令是否正确?
sfarbota

1
@sfarbota:不,这是一个错字!现在已更正。感谢您指出。
marlar

13

如果您具有源和目标,则可以与 rsync -ar --perms source/ dest

它不会传输数据,只会传输权限...


1
不,如果时间戳记不同,它将复制文件
yawniek

@yawniek -r--perms是多余的,但是如果它们是唯一不同的,则它们仍然同步烫发(这是您在“问题”中说的;如果树实际上不是相同的,则您不应该说它们是烫发的)。
克里斯·S

好吧,当时我不清楚,我的意思是树的结构是相同的。
yawniek'4

12

您可以做的一件事是使用find命令使用复制权限所需的命令来构建脚本。这是一个简单的示例,您可以使用各种printf选项做更多的事情,包括获取所有者,组ID等。

$ find /var/log -type d -printf "chmod %m %p \n" > reset_perms
$ cat reset_perms
chmod 755 /var/log
chmod 755 /var/log/apt
chmod 750 /var/log/apache2
chmod 755 /var/log/fsck
chmod 755 /var/log/gdm
chmod 755 /var/log/cups
chmod 2750 /var/log/exim4
...

1
我怀疑找到的-printf参数是GNU扩展?HP-UX查找没有它。

1
即使没有找到printf选项,也可以使用ls选项(或者,更糟糕的是,将管道传递到xargs ls -l)并保存在文件中。一两分钟的搜索和替换,然后每个文件都有一个带有chmod的脚本。
mpez0 2010年

0

两种方式:

  1. 如果它适用于您的UNIX品牌:cp -ax / src / dest
  2. 否则,这是便携式版本:(cd / src && tar cpf-)。(cd / dst && tar xpf-)

(在后一种情况下,/ dst必须存在)

编辑:对不起,我读错了。不是你问的


值得一提的是-a(用于存档)是cp的GNU补充,我从未在其他任何系统上看到过。它只是-dpR的缩写(无取消引用,递归,保留权限)。R和p选项应该在cp的任何版本中
-theotherreceive

0

我想我会写一个perl脚本来做到这一点。就像是:

#!/usr/bin/perl -nw

my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;

然后执行以下操作:

cd /some/old/orig/path/ ; find . -type d | perlscript

我把它写在脑海上,还没有经过测试。因此,请在运行前对其进行检查。这只会修复对现有目录的权限。它不会更改文件的权限,也不会创建丢失的目录。


0

我想出了这个:

find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh

它不是完全防弹的,但是可以满足我的需要。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.