Maneira padrão de duplicar as permissões de um arquivo

9

Estou tentando encontrar uma maneira POSIX padrão para duplicar as permissões de um arquivo para outro arquivo. Em um sistema GNU isso é fácil:

[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

Infelizmente, o sinalizador --reference para chmod é uma opção não padrão. Então isso está fora dos meus propósitos. Eu preferiria que fosse um one-liner, mas isso não é necessário. Em última análise, ele precisa estar na sintaxe POSIX sh.

    
por Alex 31.07.2010 / 15:40

5 respostas

6

Uma tentação é analisar ls . Evite essa tentação .

O seguinte parece funcionar, no entanto, está cheio de Kluge. Ele depende de cp mantendo as permissões do arquivo de destino. Para esta demonstração, o arquivo "template" não deve existir.

  • Copie o arquivo com as permissões que você deseja para um novo arquivo
  • Copie o arquivo que você deseja alterar para o arquivo criado na etapa anterior
  • Remove o arquivo original que você deseja alterar
  • Renomeie o arquivo intermediário para o nome do arquivo a ser alterado

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
    
por 31.07.2010 / 16:47
9

Você pode usar o comando stat para obter a permissão do arquivo:

  • Sintaxe do Mac OS X (BSD):

    chmod 'stat -f %A fileWithPerm' fileToSetPerm

  • Sintaxe do Linux (não tenho certeza):

    chmod 'stat -c %a fileWithPerm' fileToSetPerm

O símbolo ' é um backquote.

    
por 31.07.2010 / 17:12
0

Os utilitários ACL getfacl e setfacl podem ser usados para este propósito, mas eu não sei se este POSIX é compatível o suficiente. Funciona pelo menos no FreeBSD 8.0 e no Linux, mas, por outro lado, pode ser necessário instalar os utilitários do ACL.

Da página do manual:

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

Acho que getfacl e setfacl também podem operar com permissões de arquivos padrão, além das ACLs.

    
por 31.07.2010 / 17:13
0

cp -p preservará as permissões de arquivo.

    
por 01.08.2010 / 03:28
0

Uma maneira simples e portátil não é um utilitário padrão - você precisaria chame stat () no templatefile, depois chmod () no (s) arquivo (s) de destino. Isso significa usar uma linguagem como C ou outra linguagem amplamente utilizada como perl.

As permissões de acesso ao arquivo são especificadas no membro struct stat st_mode pelo 0007777 bits. A solução de Dennis está correta, se for um pouco pesada em E / S, então, para arquivos realmente grandes, pode falhar:

cp has template

Considere este exemplo não pronto para produção:

#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;
}
    
por 02.08.2010 / 14:26