2009-07-22 7 views
53

J'ai besoin d'utiliser chmod pour changer tous les fichiers récursivement à 664. Je voudrais sauter les dossiers. Je pensais faire quelque chose comme çachanger chmod pour les fichiers mais pas les répertoires

ls -lR | grep ^-r | chmod 664 

Cela ne fonctionne pas, je suppose, parce que je ne peux pas conduit dans chmod Quelqu'un sait d'une façon facile de le faire?

Merci

+1

Cela devrait être demandé à ServerFault – MoshiBin

+0

chmod devrait vraiment être en mesure de faire la différence entre les fichiers, des liens et des dossiers sur son propre. – Xeoncross

Répondre

82

Un find -exec réponse est un bon, mais il souffre de la lacune généralement non pertinente qu'il crée un sous-processus distinct pour chaque fichier. Cependant, il est parfaitement fonctionnel et ne fonctionnera mal que lorsque le nombre de fichiers obtient vraiment grand. L'utilisation de xargs permet de regrouper les noms de fichiers en grands groupes avant d'exécuter un sous-processus pour ce groupe de fichiers.

Vous devez juste faire attention à ce que, en utilisant xargs, vous gériez correctement les noms de fichiers avec des espaces incorporés, des retours à la ligne ou d'autres caractères spéciaux.

Une solution qui permet de résoudre ces deux problèmes est (en supposant que vous avez une assez bonne find et xargs mise en œuvre):

find . -type f -print0 | xargs -0 chmod 644 

Les -print0 les causes find d'annuler les noms de fichiers sur son flux de sortie avec un caractère NUL (plutôt que d'un espace) et le -0 à xargs lui fait savoir qu'il devrait s'attendre à ce que le format d'entrée.

+0

C'est génial pour trouver GNU mais malheureusement -print0 et xargs -0 ne sont pas standard, et ne fonctionnent pas par exemple. sur Solaris. Dans ce cas, utilisez l'une des autres solutions. – mark4o

+1

Je peux confirmer que cette méthode fonctionne sur Mac OSX (10.9 au moins). –

+0

@ mark4o, vous n'êtes pas limité à l'utilisation des versions Braindead fournies avec Solaris. Un grand avantage de FOSS est que vous pouvez le porter sur n'importe quel système d'exploitation (UNIXy). Je l'ai souvent fait pour AIX per-version-5L. – paxdiablo

27

Une autre façon de le faire est d'utiliser find ... -exec ... comme suit:

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

Le problème est que le -exec commence un processus chmod pour chaque fichier. L'approche xargs évite cela, et est supérieure à condition que vous ayez une version de find et xargs capable de faire face au problème des "espaces dans les chemins"; voir la réponse acceptée. Et pour l'anecdote, l'utilisation de back-ticks va se casser s'il y a trop de fichiers à chmoder, ou la longueur cumulée des chemins d'accès est trop grande.

+1

quelle est la différence entre \ et '+'? –

+2

@HowChen - Lisez 'man find'. –

+2

En fait ... c'est la différence entre ';' et '+;'. Le backslash est l'échappement de la coquille. –

2

GNU find

find /path -type f -exec chmod 644 {} +;

13

Mes deux cents succinctes ...

Linux:

$ chmod 644 `find -type f` 

OSX:

$ chmod 644 `find . -type f` 

Cela fonctionne à changer de façon récursive tous les fichiers contenus dans le répertoire courant et tous ses sous-répertoires. Si vous souhaitez cibler un répertoire différent, remplacez . avec le bon chemin:

$ chmod 644 `find /home/my/special/folder -type f` 
+0

comment spécifiez-vous quel répertoire? –

+1

Ma réponse originale couvrait ce que l'OP avait demandé: changer récursivement tous les fichiers du répertoire courant. Voir ma modification pour savoir comment l'appliquer à n'importe quel répertoire, pas seulement celui en cours. –

+1

Merci pour la solution la plus simple et la plus courte – asherrard

Questions connexes