Clonar propriedade e permissões de outro arquivo?

125

Existe um comando ou sinalizador para clonar a propriedade do usuário / grupo e as permissões em um arquivo de outro arquivo? Para tornar as permissões e propriedades exatamente as de outro arquivo?

user394
fonte

Respostas:

175

No GNU / Linux chowne chmodtem uma --referenceopção

chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile
enzotib
fonte
1
Você poderia fazer referência a esta resposta (e provavelmente citá-la) como resposta à minha pergunta: unix.stackexchange.com/questions/44253/… ? , Acho que vou ser um ótimo complemento e adoraria encontrar votos positivos para isso.
Grzegorz Wierzowiecki 31/07/2012
@GrzegorzWierzowiecki: provavelmente essa pergunta deve ser encerrada, mas é um pouco diferente disso e já tem respostas, então é melhor eu não fazer nada.
enzotib 31/07
Como você deseja e sugere. Obrigado pela ajuda, eu nunca coloquei atenção ao --referenceparâmetro de chmode chownantes :).
Grzegorz Wierzowiecki 31/07/2012
12

Em qualquer unix com utilitários GNU, como Linux (não incorporado) ou Cygwin, você pode usar chmod --referenceechown --reference .

Se o seu sistema tiver ACLs , tente os comandos getfacle setfacl. Esses comandos diferem um pouco de sistema para sistema, mas em muitos você pode usar getfacl other_file | setfacl -bnM - file_to_changepara copiar as permissões. Isso não copia a propriedade; você pode fazer isso analisando cuidadosamente ls -l other_file, assumindo que não possui nomes de usuário ou grupo que contenham espaços em branco.

LC_ALL=C ls -l other_file | {
  read -r permissions links user group stuff;
  chown -- "$user:$group" file_to_change
}
getfacl other_file | setfacl -bnM - file_to_change
Gilles
fonte
1
Você deve ter a ACL instalada e o sistema de arquivos montado com a ACL ativada.
enzotib 14/09/11
2
@enzotib Pelo menos no Linux, as ferramentas da ACL trabalharão para copiar permissões (mas não a propriedade), mesmo que o sistema de arquivos de origem e destino não suporte ACLs.
Gilles
7

Fiz um comando bash com base na resposta de Matteo :)

Código:

chmod $( stat -f '%p' "$1" ) "${@:2}"

Uso:

cp-permissions <from> <to>...

mjlescano
fonte
5
Egad! Onde você aprendeu a dizer ${*:2}? Nunca faça isso de novo! Isso falhará se algum dos nomes de arquivos contiver espaço (ou guias). Use "${@:2}". Além disso, use em "$1"vez de apenas $1.
G-Man
chmod "$(stat -c '%a' "$fromfile")" tofileno GNU Coreutils, mas você também pode usar --referencenesse caso, já que o statutilitário CLI não é POSIX, ele também diz pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.htm ls -l que não é suficiente: "A saída de ls (com as opções -l e relacionadas) contém informações que logicamente podem ser usadas por utilitários como chmod e touch para restaurar arquivos para um estado conhecido.No entanto, essas informações são apresentadas em um formato que não pode ser usado diretamente por esses utilitários ou facilmente traduzido para um formato que possa ser usado ".
Ciro Santilli escreveu
5

Se você não estiver usando um sistema com o chmod / chown do GNU (que suporta a --referenceopção), você pode tentar analisar a saída dels -l

Aqui está um pequeno script para chmod(se você tem uma visão que suporta regexes estendidos, eles podem ser escritos de uma maneira muito mais legível ...)

#!/bin/sh

reference=$1
shift
files=$*

# strip the permissions (whith extended regexes could be more readable)
OWNER=$(ls -l ${reference} | sed -e "s/.\(...\).*/\1/"       | sed -e "s/[-]//g" )
GROUP=$(ls -l ${reference} | sed -e "s/....\(...\).*/\1/"    | sed -e "s/[-]//g" )
OTHER=$(ls -l ${reference} | sed -e "s/.......\(...\).*/\1/" | sed -e "s/[-]//g" )

chmod u=${OWNER},g=${GROUP},o=${OTHER} ${files}

ATUALIZAÇÃO :

Isso é ainda mais fácil usando stat:

chmod $( stat -f '%p' ${reference} ) ${files}
Matteo
fonte
2
Em vez de analisar a ls -lsaída, você poderia analisar a statsaída.
Jfg956
@jfgagne: obrigado faz sentido Eu não sei por que não pensei nisso em primeiro lugar. Atualizei a resposta
Matteo
1
Você está usando a statsintaxe * BSD aqui. Seu chmod $(stat ...)comando não funcionará porque, %psozinho, gera muitas informações para * BSDs chmod, use %Lppara gerar apenas os bits u / g / o. Algo um pouco mais elaborado seria necessário para os bits sticky / setuid / setgid.
precisa saber é o seguinte
0

Eu queria adicionar um ajuste ao script de Matteo . Um loop for deve ser usado para validar a existência dos arquivos antes de executar o comando chmod neles. Isso deixará o erro de script mais gracioso.

Eu acho que essa é a melhor opção, pois pode ser usada para todos os sistemas operacionais * nix, como Solaris, Linux, etc.

#!/bin/sh

reference=$1
shift
files=$*

for file in $reference $files; do
  [ -f $file ] || { echo "$file does not exist"; exit 1; }
done

# strip the permissions (whith extended regexes could be more readable)
OWNER=$(ls -l ${reference} | sed -e "s/.\(...\).*/\1/" | sed -e "s/[-]//g" )
GROUP=$(ls -l ${reference} | sed -e "s/....\(...\).*/\1/" | sed -e "s/[-]//g" )
OTHER=$(ls -l ${reference} | sed -e "s/.......\(...\).*/\1/" | sed -e "s/[-]//g" )

chmod u=${OWNER},g=${GROUP},o=${OTHER} ${files}

Eu descobri que em uma das minhas máquinas Solaris 10, statnão foi encontrada. Isso pode ser um problema com minha configuração.

David
fonte
0

Isso funciona para mim:

cp -p --attributes-only <from> <to>

user172554
fonte