复制文件权限的标准方法


10

我试图找到一种标准的POSIX方法,将一个文件的权限复制到另一个文件。在GNU系统上,这很容易:

[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

不幸的是,chmod的--reference标志是非标准选项。所以这是出于我的目的。我希望它是单线的,但这不是必需的。最终,它确实需要使用POSIX sh语法。

Answers:


7

一种诱惑是解析ls避免那种诱惑

以下似乎有效,但是充满了克鲁格。它依赖于cp保留目标文件的权限。对于此演示,文件“模板”必须不存在。

  • 将具有所需权限的文件复制到文件
  • 将要更改的文件复制到上一步中创建的文件
  • 删除您要更改的原始文件
  • 重命名中间文件为要更改的文件的名称

演示:

$ 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

现在,这是一种有趣的方法。我将对此进行测试,并查看它在各种服务器上的运行情况。在我看来,它会成功。
亚历克斯

@Alex:如果有问题,请确保也使用文件所有权对其进行测试。
暂停,直到另行通知。

第一个cp命令cp has template应当用于cp -p保留模式和所有权属性。
2014年

@mernst:只有cp在文件的所有者/组(例如“用户”)与进行复制的所有者(例如,根)不同时,才需要第一个。
暂停,直到另行通知。

@丹尼斯·威拉姆森(Dennis Willamson):好的,但这是有可能的,我认为在此使用cp -p它没有任何不利影响。
mernst 2014年

12

您可以使用以下stat命令获取文件许可权:

  • Mac OS X(BSD)语法:

    chmod`stat -f%A fileWithPerm` fileToSetPerm

  • Linux语法(不确定):

    chmod`stat -c%a fileWithPerm` fileToSetPerm

`符号是反引号。


1
我认为statPOSIX不需要。它通常不可用。
暂停,直到另行通知。

stat(命令行)不是POSIX,并且不可移植。丹尼斯++
吉姆·麦克纳马拉

1

ACL实用程序getfaclsetfacl可以用于此目的,但是我不知道此POSIX是否足够兼容。至少可以在FreeBSD 8.0和Linux上运行,但是另一方面,可能必须安装ACL实用程序。

从手册页:

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

我认为getfacl和setfacl除了ACL之外还可以操作标准文件权限。


POSIX定义的ACL等是特定于实现的,因此不需要遵从。
暂停,直到另行通知。

0

cp -p 将保留文件权限。


1
这就是为什么我的答案(使用-p)中的技术适用于OP想要的功能,即复制另一个文件的权限,而不是复制文件。
暂停,直到另行通知。

0

一种可移植,直接的方法不是标准实用程序-您需要在模板文件上调用stat(),然后在目标文件上调用chmod()。这意味着使用诸如C之类的语言或诸如perl之类的另一种广泛使用的语言。

文件访问许可权在struct stat st_mode成员中由0007777位指定。Dennis的解决方案是正确的,如果I / O过多,那么对于很大的文件,它可能会失败:

cp has template

考虑以下未准备生产的示例:

#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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.