Comment supprimer le bit exécutable de manière récursive à partir de fichiers (pas de répertoires)

73

Lorsque je connecte une clé USB (FAT) à mon ordinateur Mac ou Ubuntu, tous les fichiers ont les bits exécutables définis. Après avoir copié la structure de répertoires sur mon disque dur, comment puis-je supprimer les bits exécutables de manière récursive uniquement dans les fichiers et les conserver dans les répertoires?

Mike L.
la source

Réponses:

133

Avec GNU chmod(sur Ubuntu), variante à commande unique (commençant dans le répertoire actuel):

chmod -R -x+X .

Explication:

  • -R - opérer de manière récursive
  • -x - supprimer les indicateurs exécutables pour tous les utilisateurs
  • +X - définir des indicateurs exécutables pour tous les utilisateurs s'il s'agit d'un répertoire

Dans ce cas, le capital Xs'applique uniquement aux répertoires, car tous les indicateurs de l'exécutable ont été effacés par -x. Sinon +X, active le ou les indicateurs exécutables également si l'indicateur a été défini à l'origine pour un utilisateur, un groupe ou autre.

Avec BSD chmod(présent sur Mac OS X), vous devez le faire séparément en deux commandes:

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

(Si vous souhaitez également inclure des fichiers cachés dans le répertoire principal, vous devrez probablement remplacer * par. (Point), mais cela n’a pas été testé.)

Pabouk
la source
1
Sur Ubuntu 13.04, un ajustement mineur est nécessaire:chmod -R a-x+X *
Eero Aaltonen
@EeroAaltonen: Merci pour la note. Cela pourrait se produire si votre permission umaskne permet pas xà tous Utilisez-vous default umaskou l'avez-vous changé? Pourriez-vous s'il vous plaît envoyer la sortie de la umaskcommande? Outre votre solution, il existe également cette possibilité: chmod -R a-x,+X *qui définira l’ xautorisation en fonction de votre umask. Je vais mettre à jour la réponse, mais je voudrais d’abord vérifier le comportement sous BSD / Mac OS X.
pabouk
@pabouk oopsie! C'était en fait la boîte CentOs où j'avais réglé mon umask sur 0007.
Eero Aaltonen Le
C'est juste triste ... :( J'aime la findvariante de la réponse ci-dessous pour son style combinant des outils simples qui font One Thing Well.
mikezter
2
À utiliser à la .place de *si vous voulez que cela soit appliqué à tous les fichiers
John Magnolia
46

Si vous entrez d'abord dans le bon chemin:

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

ou

chmod -x $(find . -type f)

La recherche trouve tous les fichiers de type 'f' (ce qui signifie fichier ordinaire) dans le chemin. puis appelle chmod -x sur chaque fichier. Le {} est remplacé par le nom du fichier et le \; termine la commande chmod.

Matthijs P
la source
6
Si votre findsoutien le prend, utilisez -exec ... \+plutôt que -exec ... \;- cela nécessitera moins de fork+ execs. Si ce n'est pas le cas, utilisez find ... -print0 | xargs -0 ....
éphémient
5
J'ai utilisé cette technique, mais avec "-perm +111" ajouté à la recherche, il ne reste donc que ceux de chmod pour lesquels le bit x est défini:find . -type f -perm +111 -exec chmod -x {} \;
chrish
4
+1 @Matthijs La raison pour laquelle c'est mieux que la solution de pabouk est que cette commande laisse les répertoires seuls, tandis que celle de pabouk rétablit le bit exécutable dans tous les répertoires. Il se peut que certains répertoires ne définissent pas le bit exécutable et que la commande de pabouk le définisse, alors que vous voudrez peut-être les laisser tels quels.
MariusMatutiae
la deuxième approche échouera pour les chemins contenant des espaces.
MestreLion
@ ephemient: si vos findsoutiens, -print0je suis sûr qu'ils le feront aussi-exec
MestreLion
3

Sous Linux et Unix dans une fenêtre de terminal ou sous Mac OS X, utilisez ceci dans Terminal.app:

find . -type f -print0 | xargs -0 chmod -x
utilisateur227317
la source
1
En substance, cela n’est pas différent de la réponse de Matthijs P de 2011.
slhck
Vous souvenez-vous de cette ligne de commande? Je ne peux pas
Mike L.
Voir le commentaire de l'éphémère ci-dessous, dans la réponse de Matthijs, pour voir pourquoi cette réponse est utile.
PatrickT
2

Le chmod -x+Xchemin n’a pas fonctionné pour moi non plus sur Ubuntu, j’ai donc écrit ce script minimal en python:

#!/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)

S'il peut y avoir des éléments supplémentaires fantaisistes tels que des sockets dans votre système de fichiers, vous voudrez peut-être entourer le dernier chmod d'un try / catch.

mic_e
la source