Use o comando chmod seletivamente

11

Quero definir a permissão 755 em todos os arquivos e subdiretórios em um diretório específico, mas quero executar o chmod 755 apenas para os componentes que não têm permissão 755.

find /main_directory/ -exec chmod 755 {} \;

Se o findcomando retornar uma lista longa, isso levará muito tempo. Eu sei que posso usar o comando stat para verificar a permissão no nível do arquivo Octal de cada componente e, em seguida, usar if-else para alternar a permissão do arquivo, mas existe uma abordagem de linha única usando finde xargspara verificar primeiro qual permissão o arquivo / diretório possui e, em seguida, use chmodpara alterá-lo para 755 se estiver definido para outra coisa.

Kumarjit Ghosh
fonte
6
Isso pode ser uma otimização prematura e pode nem ser mais rápida. A realização de todas essas verificações pode diminuir a velocidade. Testar para garantir que seja mais rápido, só será recompensado se você precisar fazer isso muito.
ctrl-alt-Delor
3
Você provavelmente não deseja conceder permissões de execução a todos os arquivos. Isso criará um risco de segurança. (este é um dos vetores de vírus no Windows da Microsoft: tudo é executável). No modo simbólico, você pode dizer u+rw,go+r,go-w,ugo+X- observe a capital.
ctrl-alt-Delor
Eu concordo com @ ctrl-alt-delor, mas gostaria de sugerir algo mais próximo do que você pediu, u = rwX, go = rX, que deve obter a mesma coisa.
Penguin359

Respostas:

21

Se você deseja alterar as permissões para 755arquivos e diretórios, não há benefício real em usá-lo find(pelo menos do ponto de vista de desempenho) e você pode fazer isso

chmod -R 755 /main_directory

Se você realmente deseja usar findpara evitar alterar permissões em itens que já possuem 755permissões (para evitar a atualização do carimbo de data / hora do ctime), também deve testar as permissões atuais em cada diretório e arquivo:

find /main_directory ! -perm 0755 -exec chmod 755 {} +

Ele -exec ... {} +coletará o maior número de nomes de caminhos possíveis que passarem no ! -perm 0755teste e será executado chmodem todos eles de uma só vez.

Geralmente, alguém desejaria alterar permissões em arquivos e diretórios separadamente, para que nem todos os arquivos sejam executáveis:

find /main_directory   -type d ! -perm 0755 -exec chmod 755 {} +
find /main_directory ! -type d ! -perm 0644 -exec chmod 644 {} +
Kusalananda
fonte
Funcionou como charme, obrigado. Atenciosamente, Kumarjit
Kumarjit Ghosh
1
Eu suspeito que usar em +vez de ;faz uma grande diferença aqui.
Kevin
Esta é a maneira rápida - evite um cheque. Eu usaria o find para fazer uma lista apenas dos arquivos que você tem permissão para alterar, para evitar erros de chmod nos arquivos que não podem ser alterados. <pre> <code> # rwx, rw, wx, w apenas localizamos. -user $ (whoami) -perm / 002! -perm 0755 -exec chmod 0755 {} \; # divida em duas operações find. -user $ (whoami) -perm / 002! -perm 0755> /tmp/chfiles.txt para o arquivo em $ (</ tmp / chfiles.txt) do chmod --quiet 0755 "$ {file}" done </code> </pre>
Chris Reid
@ChrisReid Observe que o loop sobre uma lista de nomes de caminhos como esse será interrompido se algum nome de caminho contiver um caractere de espaço em branco.
Kusalananda
Eu acho que você precisa alterar o Internal Field Separator (IFS) para '\ n' em um script. Essas são configurações do ambiente, a maneira como o shell as interpreta depende dos valores dessas configurações. Testo scripts em arquivos fictícios antes de usá-los para descobrir desastres desastrados, como renomear arquivos ou substituí-los. Eu gosto da maneira shell printf de definir o IFS. IFS = $ (printf "\ n") # muito legível
Chris Reid
1

Como você findobteve a -exec ... +sintaxe, não há muito sentido em usá-lo xargs, mas como você pede:

find /main_directory -not -perm 0755 | xargs chmod 755
Henrik apoia a comunidade
fonte
1
Observe também que o xargs sem -0(em combinação com o -print0find; que é a extensão GNU) pode ser bastante problemático em termos de segurança se um invasor em potencial puder criar nomes de arquivos que incluem espaços em branco ou outros caracteres especiais. Então é melhor ficar com -execquando puder
Matija Nalis
Não é necessário xargs(apenas use -exec), e se você o usar, deverá usar -print0/ -0como Matija diz.
Kevin