Como remover o bit executável recursivamente dos arquivos (não diretórios)

73

Quando conecto um pendrive USB (FAT) à minha máquina Mac ou Ubuntu, todos os arquivos têm os bits executáveis ​​definidos. Depois de copiar a estrutura de diretórios para o meu disco rígido, como removo os bits executáveis ​​recursivamente apenas dos arquivos e os mantenho nos diretórios?

Mike L.
fonte

Respostas:

132

Com a chmodvariante de comando único GNU (no Ubuntu) (iniciando no diretório atual):

chmod -R -x+X .

Explicação:

  • -R - operar recursivamente
  • -x - remova sinalizadores executáveis ​​para todos os usuários
  • +X - defina sinalizadores executáveis ​​para todos os usuários, se for um diretório

Nesse caso, o capital Xaplica-se apenas aos diretórios porque todos os sinalizadores executáveis ​​foram limpos por -x. Caso contrário, +Xdefine sinalizadores executáveis ​​também se o sinalizador foi originalmente definido para qualquer usuário, grupo ou outros.

Com o BSD chmod(presente no Mac OS X), você deve fazer isso separadamente em dois comandos:

sudo chmod -R -x * && sudo chmod -R +X *

(Se você também deseja incluir arquivos ocultos no diretório principal, é necessário alterar * para. (Point), mas ele não foi testado.)

pabouk
fonte
No Ubuntu 13.04, é necessário um pequeno ajuste:chmod -R a-x+X *
Eero Aaltonen
@EeroAaltonen: Obrigado pela observação. Isso pode acontecer se o seu umasknão permitir xpermissão para todos. Você usa o padrão umaskou o mudou? Você poderia enviar a saída do umaskcomando? Além da sua solução, há também esta possibilidade: a chmod -R a-x,+X *qual definirá a xpermissão de acordo com o seu umask. Atualizarei a resposta, mas gostaria de verificar o comportamento do BSD / Mac OS X primeiro.
precisa saber é
@pabouk oopsie! Na verdade, foi a caixa CentOS onde eu tinha o meu umask para 0007.
Eero Aaltonen
Isso é apenas triste ... :( Eu gosto da findvariante na resposta abaixo para o seu estilo de combinar ferramentas simples que fazer uma coisa bem.
mikezter
2
Use .em vez de *se pretender que esta a ser aplicado a todos os arquivos
John Magnolia
46

Se você entrar no caminho correto primeiro:

find . -type f -exec chmod -x {} \;

ou

chmod -x $(find . -type f)

A localização localiza todos os arquivos do tipo 'f' (que significa arquivo regular) no caminho. e depois chama chmod -x em cada arquivo. O {} é substituído pelo nome do arquivo e o \; finaliza o comando chmod.

Matthijs P
fonte
6
Se o seu findsuporte, use em -exec ... \+vez de -exec ... \;- exigirá menos fork+ execs. Caso contrário, use find ... -print0 | xargs -0 ....
ephemient
5
Eu usei esta técnica, mas com "-perm 111" adicionada ao achado tão queridos só de chmod que têm o conjunto x-bit:find . -type f -perm +111 -exec chmod -x {} \;
ChrisH
4
+1 @Matthijs A razão pela qual isso é melhor que a solução do pabouk é que esse comando deixa os diretórios em paz, enquanto o pabouk redefine o bit executável em todos os diretórios. Pode haver alguns diretórios em que o bit executável não está definido e o comando pabouk o define, enquanto um pode querer deixá-los como estão.
MariusMatutiae
a segunda abordagem falhará nos caminhos que contêm espaços.
MestreLion 16/09/2015
@ephemient: se os seus findsuportes -print0eu tenho certeza que também irá apoiar-exec
MestreLion
3

No Linux e Unix em uma janela de terminal ou no Mac OS X, use-o no Terminal.app:

find . -type f -print0 | xargs -0 chmod -x
user227317
fonte
1
Esta é, em essência, não diferente de resposta de Matthijs P a partir de 2011.
slhck
Você consegue se lembrar dessa linha de comando? Não posso.
Mike L.
Veja o comentário do ephemient abaixo da resposta de Matthijs para ver por que essa resposta é útil.
PatrickT
2

O chmod -x+Xcaminho também não funcionou para mim no ubuntu, por isso escrevi este script python mínimo:

#!/usr/bin/python3
import os
for par, dirs, files in os.walk('.'):
    for d in dirs:
        os.chmod(par + '/' + d, 0o755)
    for f in files:
        os.chmod(par + '/' + f, 0o644)

Se houver algum material extra sofisticado, como soquetes em seu sistema de arquivos, convém cercar o último chmod com uma tentativa / captura.

ratos
fonte