Copiar permissões para uma árvore idêntica no linux / unix


22

Eu tenho uma árvore de arquivos com permissão correta. então eu tenho uma árvore idêntica (filewise) (com conteúdo de arquivo diferente) com permissões erradas.

como posso transferir o layout de permissões de uma árvore para outra?

Respostas:


8

Isso pode ser feito com a seguinte linha de shell:

D1=foo; D2=foo2; for entry in $(find $D1  -exec stat -f "%N:%Mp%Lp" {} \;); do $(echo $entry | sed 's#'$D1'#'$D2'#' | awk -F: '{printf ("chmod %s %s\n", $2, $1)}') ; done

simplesmente defina o valor correto para as variáveis ​​D1 e D2, aponte-os para os diretórios de origem e destino, execute e os dirs terão permissões em sincronia.


1
Isso pressupõe que o status esteja presente. Descobri, lamentavelmente, que o comando stat geralmente não está presente.
Mei

@ David, eu não conheço um sistema desse tipo que não tem status. Mas é bastante trivial usar a seguinte versão "octal ls" e acomodar a solução fornecida de acordo: alias ols = "ls -la | awk '{k = 0; for (i = 0; i <= 8; i ++) k + = ((substr (\ $ 1, i + 2,1) ~ / [rwx] /) * 2 ^ (8-i)); if (k) printf (\ "% 0o \", k); print} ' "
drAlberT 25/08/09

Interrompe quando qualquer caminho envolvido contém algum tipo de caractere especial (espaço em branco, começa com traços, etc.).
n.st

31

Acabei de aprender uma maneira nova e simples de fazer isso:

getfacl -R /path/to/source > /root/perms.acl

Isso irá gerar uma lista com todas as permissões e propriedades.

Em seguida, vá para um nível acima do destino e restaure as permissões com

setfacl --restore=/root/perms.acl

A razão pela qual você precisa estar um nível acima é que todos os caminhos no perms.acl são relativos.

Deve ser feito como root.


essa é uma maneira muito direta e simples de fazer backup e restaurar permissões. Observe, porém, que getfacle setfaclnão está necessariamente presente em todos os sistemas.
the-wabbit

É correto ter .acno primeiro comando e .aclno segundo?
precisa saber é o seguinte

1
@sfarbota: Não, foi um erro de digitação! Corrigido agora. Obrigado por apontar isso.
Marlar

13

Se você possui a origem e o destino, pode sincronizar suas permissões com rsync -ar --perms source/ dest

Não irá transferir os dados, apenas permissões ...


1
Não, ele irá copiar arquivos se timestamps diferem
yawniek

@yawniek The -re --permssão redundantes, mas isso ainda sincroniza permanentemente se forem a única coisa diferente (que foi o que você disse na pergunta; se as árvores não forem realmente idênticas, você não deveria ter dito que eram).
Chris S

ok, eu não estava claro então, eu quis dizer que a estrutura da árvore é a mesma.
yawniek

12

Uma coisa que você pode fazer é usar o comando find para criar um script com os comandos necessários para copiar as permissões. Aqui está um exemplo rápido: você poderia fazer muito mais com as várias opções printf, incluindo obter o proprietário, o ID do grupo e assim por diante.

$ find /var/log -type d -printf "chmod %m %p \n" > reset_perms
$ cat reset_perms
chmod 755 /var/log
chmod 755 /var/log/apt
chmod 750 /var/log/apache2
chmod 755 /var/log/fsck
chmod 755 /var/log/gdm
chmod 755 /var/log/cups
chmod 2750 /var/log/exim4
...

1
Eu suspeito que o argumento -printf a encontrar é uma extensão GNU? A localização do HP-UX não a possui.
Mei

1
Mesmo sem a opção printf para encontrar, pode-se usar a opção ls (ou, na pior das hipóteses, canalizar para xargs ls -l) e salvar em um arquivo. Um ou dois minutos de pesquisa e substituição, e um terá um script com chmod para cada arquivo.
mpez0

0

Dois caminhos:

  1. Se funcionar na sua marca do UNIX: cp -ax / src / dest
  2. Caso contrário, esta é a versão portátil: (cd / src && tar cpf -.) | (cd / dst && tar xpf -)

(no último caso / dst deve existir)

Edit: desculpe, eu interpretei errado. Não é o que você pediu.


Vale ressaltar que -a (para arquivamento) é uma adição GNU ao cp, nunca vi em nenhum outro sistema. É apenas uma abreviação de -dpR (sem permissão de des-referência, recursiva e preservação). As opções de R e p deve ser em qualquer versão do cp
theotherreceive

0

Eu acho que escreveria um script perl para fazer isso. Algo como:

#!/usr/bin/perl -nw

my $dir = $_;
my $mode = stat($dir)[2];
my $pathfix = "/some/path/to/fix/";
chmod $mode, $pathfix . $dir;

Então faça algo parecido com isto:

cd /some/old/orig/path/ ; find . -type d | perlscript

Eu escrevi isso em cima da minha cabeça e não foi testado; então verifique-o antes de deixá-lo correr desenfreado. Isso apenas corrige permissões nos diretórios existentes; não altera as permissões nos arquivos, nem cria diretórios ausentes.


0

Eu vim com isso:

find $SOURCE -mindepth 1 -printf 'chmod --reference=%p\t%p\n'|sed "s/\t$SOURCE/ $DEST/g"|sh

Não é totalmente à prova de balas, mas faz o que eu preciso.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.