i have a tree of files with correct permission. then i have a (filewise) identical tree (with different file contents tough) with wrong permissions.
how can i transfer the permissions layout from one tree to another?
i have a tree of files with correct permission. then i have a (filewise) identical tree (with different file contents tough) with wrong permissions.
how can i transfer the permissions layout from one tree to another?
I just learned a new and simple way to accomplish this:
getfacl -R /path/to/source > /root/perms.acl
This will generate a list with all permissions and ownerships.
Then go to one level above the destination and restore the permissions with
setfacl --restore=/root/perms.acl
The reason you have to be one level above is that all paths in perms.acl are relative.
Should be done as root.
If you have the source and dest, you can synchronize your permissions with
rsync -ar --perms source/ dest
It will not transfer the data, just permissions...
One thing you could do is use the find command to build a script with the commands you need to copy the permissions. Here is a quick example, you could do a lot more with the various printf options, including get the owner, group id, and so on.
$ 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
...
It can be done with the following shell line:
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
simply set the right value for D1 and D2 variables, point them to the source and destination directories, run and the dirs will have permissions in sync.
Two ways:
(in the latter case /dst must exist)
Edit: sorry, I misread. Not what you asked.
I think I'd write a perl script to do it. Something like:
#!/usr/bin/perl -nw
my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;
Then do something like this:
cd /some/old/orig/path/ ; find . -type d | perlscript
I wrote this off the top of my head, and it has not been tested; so check it before you let it run rampant. This only fixes permissions on directories that exist; it won't change permissions on files, nor will it create missing directories.
I came up with this:
find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh
It is not fully bullet proof, but does what I need.