web-dev-qa-db-fra.com

Comment récursivement chmod tous les répertoires sauf les fichiers?

Comment chmod 755 tous les répertoires mais aucun fichier (récursivement)?

Inversement, comment chmod uniquement des fichiers (récursivement) mais pas de répertoire?

555
Olivier Lalonde

Pour donner récursivement les privilèges directory read & execute:

find /path/to/base/dir -type d -exec chmod 755 {} +

Pour donner récursivement les privilèges files read:

find /path/to/base/dir -type f -exec chmod 644 {} +

Ou, s'il y a beaucoup d'objets à traiter:

chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)

Ou, pour réduire le frai chmod:

find /path/to/base/dir -type d -print0 | xargs -0 chmod 755 
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
778
nik

Une raison courante pour ce genre de chose est de définir les répertoires sur 755 mais les fichiers sur 644. Dans ce cas, il existe un moyen légèrement plus rapide que l'exemple find de nik:

chmod -R u+rwX,go+rX,go-w /path

Sens:

  • -R = récursivement;
  • u+rwX = Les utilisateurs peuvent lire, écrire et exécuter.
  • go+rX = groupe et les autres peuvent lire et exécuter;
  • go-w = groupe et les autres ne peuvent pas écrire

La chose importante à noter ici est que la majuscule X agit différemment de la minuscule x. Dans le manuel, nous pouvons lire:

Les bits execute/search si le fichier est un répertoire ou si l'un des bits execute/search est défini dans le mode d'origine (non modifié).

En d'autres termes, chmod u + X sur un fichier ne définira pas le bit d'exécution; et g + X ne le définira que s'il est déjà défini pour l'utilisateur.

281
bobince

Si vous voulez vous assurer que les fichiers sont définis sur 644 et que certains fichiers du chemin contiennent l'indicateur d'exécution, vous devez d'abord supprimer l'indicateur d'exécution. + X ne supprime pas l'indicateur d'exécution des fichiers qui l'ont déjà.

Exemple:

chmod -R ugo-x,u+rwX,go+rX,go-w path

Mise à jour: cela semble échouer car la première modification (ugo-x) rend le répertoire non exécutable, de sorte que tous les fichiers qu'il contient ne sont pas modifiés.

13
mpolden

J'ai décidé d'écrire un petit script pour cela moi-même.

Script récursif chmod pour les répertoires et/ou fichiers - Gist :

chmodr.sh

#!/bin/sh
# 
# chmodr.sh
#
# author: Francis Byrne
# date: 2011/02/12
#
# Generic Script for recursively setting permissions for directories and files
# to defined or default permissions using chmod.
#
# Takes a path to recurse through and options for specifying directory and/or 
# file permissions.
# Outputs a list of affected directories and files.
# 
# If no options are specified, it recursively resets all directory and file
# permissions to the default for most OSs (dirs: 755, files: 644).

# Usage message
usage()
{
  echo "Usage: $0 PATH -d DIRPERMS -f FILEPERMS"
  echo "Arguments:"
  echo "PATH: path to the root directory you wish to modify permissions for"
  echo "Options:"
  echo " -d DIRPERMS, directory permissions"
  echo " -f FILEPERMS, file permissions"
  exit 1
}

# Check if user entered arguments
if [ $# -lt 1 ] ; then
 usage
fi

# Get options
while getopts d:f: opt
do
  case "$opt" in
    d) DIRPERMS="$OPTARG";;
    f) FILEPERMS="$OPTARG";;
    \?) usage;;
  esac
done

# Shift option index so that $1 now refers to the first argument
shift $(($OPTIND - 1))

# Default directory and file permissions, if not set on command line
if [ -z "$DIRPERMS" ] && [ -z "$FILEPERMS" ] ; then
  DIRPERMS=755
  FILEPERMS=644
fi

# Set the root path to be the argument entered by the user
ROOT=$1

# Check if the root path is a valid directory
if [ ! -d $ROOT ] ; then
 echo "$ROOT does not exist or isn't a directory!" ; exit 1
fi

# Recursively set directory/file permissions based on the permission variables
if [ -n "$DIRPERMS" ] ; then
  find $ROOT -type d -print0 | xargs -0 chmod -v $DIRPERMS
fi

if [ -n "$FILEPERMS" ] ; then
  find $ROOT -type f -print0 | xargs -0 chmod -v $FILEPERMS
fi

Il fait essentiellement le chmod récursif mais offre également un peu de flexibilité pour les options de ligne de commande (définit les autorisations de répertoire et/ou de fichier, ou les exclut, il réinitialise automatiquement tout à 755-644). Il vérifie également quelques scénarios d'erreur.

J'ai aussi écrit à ce sujet sur mon blog .

4
francisbyrne

Pour donner récursivement les privilèges directory read & execute:

find /path/to/base/dir -type d -exec chmod 755 {} \;

Pour donner récursivement les privilèges files read:

find /path/to/base/dir -type f -exec chmod 644 {} \;

Mieux vaut tard que de ne jamais me laisser améliorer la réponse de nik du point de vue de la correction. Ma solution est plus lente, mais elle fonctionne avec n'importe quel nombre de fichiers, avec n'importe quels symboles dans les noms de fichiers, et vous pouvez l'exécuter avec Sudo normalement (mais attention, il pourrait détecter différents fichiers avec Sudo).

2
Peter K

Essayez ce script python; il ne nécessite aucune génération de processus et ne fait que deux appels système par fichier. Mis à part une implémentation en C, ce sera probablement le moyen le plus rapide de le faire (j'en avais besoin pour réparer un système de fichiers de 15 millions de fichiers, qui étaient tous définis à 777)

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

Dans mon cas, un try/catch était requis autour du dernier chmod, car certains fichiers spéciaux ont échoué.

0
mic_e