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?


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.

| improve this answer | |
  • 1
    This assumes that stat is present. I've found, regrettably, that the command stat is often not present. – Mei Aug 25 '09 at 9:02
  • 1
    @David, I don't know of such a system lacking of stat. But it is quite trivial to use the following "octal ls" version and accommodate the given solution accordingly: 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 Aug 25 '09 at 12:01
  • Breaks when any path involved contains any sort of special character (whitespace, starts with dashes, etc). – n.st Aug 4 '17 at 17:13

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.

| improve this answer | |
  • this is a very straightforward and simple way to backup and restore permissions. Note however that getfacl and setfacl are not necessarily present on all systems. – the-wabbit Oct 24 '13 at 14:58
  • Is it correct to have .ac in the first command and .acl in the second? – sfarbota Aug 2 '17 at 21:54
  • 1
    @sfarbota: No, it was a typo! Corrected now. Thanks for pointing it out. – marlar Aug 4 '17 at 15:25

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...

| improve this answer | |
  • 1
    nope, it will copy files if timestamps differ – yawniek Aug 25 '09 at 8:50
  • @yawniek The -r and --perms are redundant, but this still sync perms if they are the only thing that is different (which is what you said in the Question; if the trees are not actually identical you should not have said that they were). – Chris S Feb 7 '12 at 13:46
  • ok i was unclear then, i meant that the tree-structure is the same. – yawniek Apr 1 '12 at 23:21

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
| improve this answer | |
  • 1
    I suspect the -printf argument to find is a GNU extension? HP-UX find doesn't have it. – Mei Aug 25 '09 at 9:04
  • 1
    Even without the printf option to find, one can use the ls option (or, at worst, pipe to xargs ls -l) and save in a file. A minute or two of search and replace, and one will have a script with chmod for each file. – mpez0 Feb 26 '10 at 14:34

Two ways:

  1. If it works on your brand of UNIX: cp -ax /src /dest
  2. Or if not, this is the portable version: (cd /src && tar cpf - .) | (cd /dst && tar xpf -)

(in the latter case /dst must exist)

Edit: sorry, I misread. Not what you asked.

| improve this answer | |
  • It's worth mentioning that -a (for archive) is a GNU addition to cp, I've never seen it on any other system. It's just short for -dpR (no de-reference, recursive, preserve permissions). The R and p options should be in any version of cp – theotherreceive Aug 25 '09 at 8:34

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.

| improve this answer | |

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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.