(From : https://stackoverflow.com/questions/15245144/copy-file-permissions-but-not-files, closed because off-topic)

I have two copies of the same directory tree. They almost have the same files in both (one version may have a couple extra or missing files). However, most of the files are in common to both directories (have the same relative paths and everything).

Assume these are in directories:

version1/
version2/

The problem is that the permissions in version1/ got messed up, and I would like to copy over the permissions from version2/, but do it without replacing the files in version1/ which are newer.

Is there an automated way to do this via shell commands or scripts?

GNU cp knows the --attributes-only flag since coreutils 8.6

--attributes-only don't copy the file data, just the attributes

  • 1
    My version doesn't seem to have that flag, and some posts seem to have scary warnings for example. – shearn89 Feb 5 '15 at 13:06

My version of cp doesn't have the --attributes-only flag, so I worked up this. Briefly tested on simple folders, YMMV.

$> ls
version1/
version2/
$> ls -l version1/1/a
-rw-rw-r-- 1 alex alex 0 Feb  5 12:49 version1/1/a
$> ls -l version2/1/a
-rwxrwxrwx 1 alex alex 0 Feb  5 12:49 version1/1/a

$> find version1 -type f -printf '%P\n' | xargs -I {} \
    chmod --reference=version1/{} version2/{}

$> ls -l version2/1/a
-rw-rw-r-- 1 alex alex 0 Feb  5 12:49 version1/1/a

You can, but i don't think in an "automated way" !

GNU chown and GNU chmod have a --reference=RFILE parameter you can use.

chown --reference=RFILE yourfile
chmod --reference=RFILE yourfile

It uses RFILE settings (permissions, owner, group, etc..) and copies them to yourfile.

the manual explains in more detail.

up vote 0 down vote accepted

In my case I resolved by using "stat" command with "find" and "vi" to create a script that applies permissions.

cd version1/
find . -exec stat -c '%a %n' "{}" \; > setPerm.sh
vi setPerm.sh

Into "vi" I inserted into all the lines the "chmod" command: %s/^/chmod /g I copied the script in version2/ directory and executed it.

Other solutions seems valid but I do not tested them in case.

Inspired by Mariano Paniga's answer, I think I have a better one, that don't need to vi and search/replace commands. I'm even want to copy the ownership info too (uid/gid).

cd version1/
find . -exec stat -c 'chmod %a %n; chown %U:%G %n' "{}" \; > /tmp/setPerm.sh
chmod u+x /tmp/setPerm.sh
cd ../version2
/tmp/setPerm.sh

You may customize the commands inside stat -c '...' into anything you want. For all the available options, see man stat.

  • Does your script handle names with embedded newlines? – Deer Hunter Apr 22 '15 at 10:18
  • @deer-hunter It should work as-is, if not, you may add a quote ".." around the filename part. – Tomofumi Apr 23 '15 at 3:13

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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