Respostas:
No GNU / Linux chown
e chmod
tem uma --reference
opção
chown --reference=otherfile thisfile
chmod --reference=otherfile thisfile
--reference
parâmetro de chmod
e chown
antes :).
Em qualquer unix com utilitários GNU, como Linux (não incorporado) ou Cygwin, você pode usar chmod --reference
echown --reference
.
Se o seu sistema tiver ACLs , tente os comandos getfacl
e setfacl
. Esses comandos diferem um pouco de sistema para sistema, mas em muitos você pode usar getfacl other_file | setfacl -bnM - file_to_change
para 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
Fiz um comando bash com base na resposta de Matteo :)
Código:
chmod $( stat -f '%p' "$1" ) "${@:2}"
Uso:
cp-permissions <from> <to>...
${*: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
.
chmod "$(stat -c '%a' "$fromfile")" tofile
no GNU Coreutils, mas você também pode usar --reference
nesse caso, já que o stat
utilitá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 ".
Se você não estiver usando um sistema com o chmod / chown do GNU (que suporta a --reference
opçã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}
ls -l
saída, você poderia analisar a stat
saída.
stat
sintaxe * BSD aqui. Seu chmod $(stat ...)
comando não funcionará porque, %p
sozinho, gera muitas informações para * BSDs chmod
, use %Lp
para gerar apenas os bits u / g / o. Algo um pouco mais elaborado seria necessário para os bits sticky / setuid / setgid.
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, stat
não foi encontrada. Isso pode ser um problema com minha configuração.
Isso funciona para mim:
cp -p --attributes-only <from> <to>