Unix: Is there a way to "copy" file or directory permissions?

14

3

I have two files in a directory. One has correct permissions and the other has not. Is there a way I can "copy" the set of permissions from one file to another?

Svish

Posted 2010-02-28T15:09:11.307

Reputation: 27 731

Answers

15

The GNU version of the chmod utility can copy the mode from one file (RFile) to another (file).

chmod --reference=RFile file

GNU coreutils is found in most Linux distributions and Cygwin, among other places. Not all chmod implementations provide this option.

Jeremy L

Posted 2010-02-28T15:09:11.307

Reputation: 2 587

Hm... looks like this is supposed to work, but not supported on Mac OS X? There I only get illegal option... – Svish – 2010-02-28T16:18:08.810

2chmod is not a bash builtin command. it is a separate utility available on many unixes. the --reference option is included in the GNU version; OSX probably uses a chmod that originates with BSD instead. OSX man chmod : http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man1/chmod.1.html – quack quixote – 2010-02-28T16:31:20.993

Svish, you might consider installing the GNU versions through MacPorts. – Jeremy L – 2010-03-01T23:31:55.313

Just figured that it would be useful to mention here that cp -dpR <source-file> <dest-file> will, when copying a file, copy permissions as well as the file.r – LawrenceC – 2011-03-14T13:57:36.143

1

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.

Ikem Krueger

Posted 2010-02-28T15:09:11.307

Reputation: 131

0

try this:

find /PATH/TO/TARGET -exec chmod --reference /PATH/TO/SOURCE/{} {} \;

this would go up recursivly and chmod every file, if two directory don't match on files you will see lots of "No such file or directory" error.

bersam

Posted 2010-02-28T15:09:11.307

Reputation: 101

find /home/myubuntuuser/Desktop/test1 -exec chmod --reference /home/myubuntuuser/Desktop/test2/{} {} \; – Rick Sanchez – 2018-06-03T12:18:41.697

chmod: failed to get attributes of '/home/myubuntuuser/Desktop/test2//home/myubuntuuser/Desktop/test1': No such file or directory chmod: failed to get attributes of '/home/myubuntuuser/Desktop/test2//home/myubuntuuser/Desktop/test1/111.txt': No such file or directory chmod: failed to get attributes of '/home/myubuntuuser/Desktop/test2//home/myubuntuuser/Desktop/test1/222.txt': No such file or directory chmod: failed to get attributes of '/home/myubuntuuser/Desktop/test2//home/myubuntuuser/Desktop/test1/333.txt': No such file or directory – Rick Sanchez – 2018-06-03T12:18:49.070

tested it on 2 folders: test1 and test2. each have the same files 111/222/333.txt with different permissions. test1 has the default ones. test2 has 777 permissions. this is the error i get. – Rick Sanchez – 2018-06-03T12:19:49.993

0

You can use getfacl to retrieve the full listing of file permissions, owner, group, and additional ACLs (access control lists).

$ getfacl filename.txt
# file: filename.txt
# owner: score
# group: score
user::rw-
group::---
other::---

If you save that output to a file (e.g. acl.txt), you can then restore from this format with setfacl --restore acl.txt. If you only want to restore a single file, and that file has a different filename to the original, you will want to use setfacl --set-file acl.txt filename.txt (where filename.txt is the new filename).

Steps

  1. Save original permissions to acl.txt:

    $ getfacl filename.txt > acl.txt
    
  2. Overwrite permissions (for demonstration; this is just so that you can see that restoring it in the next step works)

    $ chmod 777 filename.txt
    $ sudo chown nobody:root filename.txt
    $ ls -l filename.txt
    -rwxrwxrwx 1 nobody root 0 Jan  8 14:24 filename.txt
    
  3. Use setfacl to restore correct permissions from acl.txt:

    $ sudo setfacl --restore acl.txt
    $ ls -l filename.txt
    -rw------- 1 score score 0 Jan  8 14:24 filename.txt
    

The filename is taken from the # file: comment generated by getfacl, so there is no need to specify it on the command line.

If you want to restore those permissions to a different file, you can use --set-file instead of --restore like so:

$ setfacl --set-file acl.txt second_filename.txt

Example

If you end up overwriting the permissions on some files in /usr, but you don't know what files you have overwritten, you can usually fix it by restoring from another similarly configured system.

  1. Backup permissions from working system (note: getfacl generates relative paths, so ensure you cd to a consistent location on both machines)

    # cd /
    # getfacl -R usr > /root/acls.txt
    
  2. Copy the ACL dump to the system with broken permissions

    $ scp root@working-system:/root/acls.txt .
    $ scp acls.txt root@broken-system:/root/
    
  3. Restore the ACL dump to overwrite the broken permissions with those from the known good machine

    # cd /
    # setfacl --restore /root/acls.txt
    

Score_Under

Posted 2010-02-28T15:09:11.307

Reputation: 671