Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to find a standard POSIX way to duplicate one file's permissions to another file. On a GNU system this is easy:

[alexmchale@bullfrog ~]$ ls -l hardcopy.*
-rw-r--r-- 1 alexmchale users 2972 Jul  8 20:40 hardcopy.1
---------- 1 alexmchale users 2824 May 14 13:45 hardcopy.4
[alexmchale@bullfrog ~]$ chmod --reference=hardcopy.1 hardcopy.4
[alexmchale@bullfrog ~]$ ls -l hardcopy.*
-rw-r--r-- 1 alexmchale users 2972 Jul  8 20:40 hardcopy.1
-rw-r--r-- 1 alexmchale users 2824 May 14 13:45 hardcopy.4

Unfortunately, the --reference flag to chmod is a non-standard option. So that is out for my purposes. I would prefer it to be a one-liner, but that's not necessary. Ultimately, it does need to be in POSIX sh syntax.

share|improve this question

5 Answers 5

up vote 5 down vote accepted

One temptation is to parse ls. Avoid that temptation.

The following seems to work, however it is full of teh Kluge. It relies on cp retaining the permissions of the target file. For this demo, the file "template" must not already exist.

  • Copy the file with the permissions you want to a new file
  • Copy the file that you want to change to the file created in the previous step
  • Remove the original file that you want to change
  • Rename the intermediate file to the name of the file to be changed

Demo:

$ echo "contents of has">has
$ echo "contents of wants">wants
$ chmod ug+x has     # just so it's different - represents the desired permissions
$ cp has template
$ cat has
contents of has
$ cat wants
contents of wants
$ cat template
contents of has
$ ls -l has wants template
-rwxr-xr-- 1 user user 16 2010-07-31 09:22 has
-rwxr-xr-- 1 user user 16 2010-07-31 09:23 template
-rw-r--r-- 1 user user 18 2010-07-31 09:22 wants
$ cp wants template
$ ls -l has wants template
-rwxr-xr-- 1 user user 16 2010-07-31 09:22 has
-rwxr-xr-- 1 user user 18 2010-07-31 09:24 template
-rw-r--r-- 1 user user 18 2010-07-31 09:22 wants
$ cat template
contents of wants
$ rm wants
$ mv template wants
$ ls -l has wants
-rwxr-xr-- 1 user user 16 2010-07-31 09:22 has
-rwxr-xr-- 1 user user 18 2010-07-31 09:24 wants
$ cat has
contents of has
$ cat wants
contents of wants
share|improve this answer
    
Now that's an interesting approach. I'm going to test this out and see how well it works against various servers. It seems to me like it'll do the trick. –  Alex Aug 1 '10 at 0:00
    
@Alex: make sure to test it with file ownership, too, if that's a concern. –  Dennis Williamson Aug 1 '10 at 1:28
    
The first cp command, cp has template, should use cp -p to preserve the mode and ownership attributes. –  mernst Dec 23 at 5:40
    
@mernst: That's only necessary for the first cp if the owner/group of the file (e.g. "user") is different from the one doing the copying (e.g. root). –  Dennis Williamson Dec 23 at 14:03
    
@Dennis Willamson: OK, but that is a possibility and I don't see any downside to using cp -p there. –  mernst 2 days ago

You can use the stat command to get the file permission :

  • Mac OS X (BSD) syntax :

    chmod `stat -f %A fileWithPerm` fileToSetPerm

  • Linux syntax (not sure) :

    chmod `stat -c %a fileWithPerm` fileToSetPerm

The ` symbol is a backquote.

share|improve this answer
1  
I don't think stat is required by POSIX. It's often not available. –  Dennis Williamson Jul 31 '10 at 17:52
    
stat (command line) is not POSIX, and is not portable. Dennis++ –  jim mcnamara Aug 2 '10 at 11:38

ACL utilities getfacl and setfacl can be used for this purpose, but I don't know if this POSIX compliant enough. Works at least in FreeBSD 8.0 and Linux, but on the other hand one might have to install the ACL utilities.

From the man-page:

getfacl file1 | setfacl -b -n -M - file2
Copy ACL entries from file1 to file2.

I think getfacl and setfacl can operate also standard file permissions in addition to ACL's.

share|improve this answer
    
ACLs and such are defined by POSIX is implementation-specific, so it's not required for compliance. –  Dennis Williamson Jul 31 '10 at 17:56

cp -p will preserve file permissions.

share|improve this answer
1  
That's why the technique in my answer (of not using -p) works for what the OP wants which is to duplicate permissions for a different file, not a duplicate of the file. –  Dennis Williamson Aug 1 '10 at 1:45

One portable, straightforward way is not a standard utility - you would need to call stat() on the templatefile, then chmod() on the destination file(s). This means using a language like C or another widely used language like perl.

The file access permissions are specified in the struct stat st_mode member by the 0007777 bits. Dennis' solution is correct, if a bit heavy on I/O, so for really big files it may fail:

cp has template

Consider this not-ready-for-production example:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

mode_t 
getperm(const char *template_file)
{
    struct stat st;
    if(stat(template_file, &st)==-1)
    {
       perror("Cannot stat file");
       exit(1);
    }
    return st.st_mode;
}

int main(int argc, char **argv)
{    
    mode_t mode=getperm(argv[1]);
    int i=0;
    for(i=2; argv[i]!=NULL; i++)    
    {
       if(chmod(argv[i], mode)==-1)
          fprintf(stderr, "Permissions failed on %s:\n\t%s\n",
              argv[i], strerror(errno));
    }       
    return 0;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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