9

Я пытаюсь найти стандартный способ 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

К сожалению, флаг --reference для chmod является нестандартной опцией. Так что это для моих целей. Я бы предпочел, чтобы он был однострочным, но в этом нет необходимости. В конечном счете, он должен быть в синтаксисе POSIX sh.

5 ответов5

10

Вы можете использовать команду stat для получения разрешения на файл:

  • Синтаксис Mac OS X (BSD):

    chmod `stat -f% A fileWithPerm` fileToSetPerm

  • Синтаксис Linux (не уверен):

    chmod `stat -c% a fileWithPerm` fileToSetPerm

`Символом является кавычка.

6

Один соблазн - разобрать ls . Избегайте этого искушения .

Следующее, кажется, работает, однако оно полно Kluge. Он полагается на то, что 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
0

Для этой цели могут быть использованы утилиты ACL getfacl и setfacl , но я не знаю, достаточно ли это POSIX-совместимо. Работает по крайней мере в FreeBSD 8.0 и Linux, но с другой стороны, возможно, придется установить утилиты ACL.

С man-страницы:

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

Я думаю, что getfacl и setfacl могут работать со стандартными правами доступа к файлам в дополнение к ACL.

0

Один портативный, простой способ не является стандартной утилитой - вам нужно вызвать stat() для файла шаблона, а затем chmod() для файла (ов) назначения. Это означает использование языка, подобного C, или другого широко используемого языка, такого как perl.

Права доступа к файлу указываются в элементе struct stat st_mode с помощью 0007777 битов. Решение Денниса правильное, если оно немного тяжелое для ввода-вывода, поэтому для действительно больших файлов оно может дать сбой:

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;
}
0

cp -p сохранит права доступа к файлам.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .