Comment chmoder récursivement tous les répertoires sauf les fichiers ?
Comment chmoder 755 tous les répertoires mais aucun fichier (récursivement) ?
Inversement, comment chmoder seulement les fichiers (récursivement) mais aucun répertoire ?
Comment chmoder 755 tous les répertoires mais aucun fichier (récursivement) ?
Inversement, comment chmoder seulement les fichiers (récursivement) mais aucun répertoire ?
Pour donner récursivement aux répertoires des privilèges de lecture et d'exécution :
find /path/to/base/dir -type d -exec chmod 755 {} +
Pour donner récursivement aux fichiers des privilèges de lecture :
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 chmod
frai :
find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
Une raison courante pour ce genre de choses est de fixer les répertoires à 755 mais les fichiers à 644. Dans ce cas, il y a un moyen légèrement plus rapide que l'exemple de nik find
:
chmod -R u+rwX,go+rX,go-w /path
Signification :
-R
= récursivement ; u+rwX
= les utilisateurs peuvent lire, écrire et exécuter ; go+rX
= groupe et autres peuvent lire et exécuter ; go-w
= groupe et 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 d'exécution/de recherche si le fichier est un répertoire ou si l'un des bits d'exécution/de recherche est défini dans le mode original (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.
Si vous voulez vous assurer que les fichiers sont définis sur 644 et qu'il y a des fichiers dans le chemin d'accès qui ont le drapeau d'exécution, vous devrez d'abord supprimer le drapeau 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 parce que la première modification (ugo-x) rend le répertoire non exécutable, donc tous les fichiers en dessous ne sont pas modifiés.
J'ai décidé d'écrire un petit script pour cela moi-même. Script chmod récursif pour 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 permissions de répertoire et/ou de fichier, ou exclut les deux ; il réinitialise automatiquement tout à 755-644). Il vérifie également quelques scénarios d'erreur.
J'ai également écrit à ce sujet sur mon blog .
To recursively give directories read&execute privileges :
find /path/to/base/dir -type d -exec chmod 755 {} \;
To recursively give files read privileges :
find /path/to/base/dir -type f -exec chmod 644 {} \;
Better late than never let me upgrade nik’s answer on the side of correctness. Ma solution est plus lente, mais elle fonctionne avec n'importe quel nombre de fichiers, avec n'importe quel symbole dans les noms de fichiers, et vous pouvez l'exécuter avec sudo normalement (mais attention au fait qu'il pourrait découvrir des fichiers différents avec sudo).
Essayez ce script python ; il ne nécessite aucune génération de processus et ne fait que deux appels système par fichier. En dehors d'une implémentation en C, ce sera probablement la manière la 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 réglés sur 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 a été nécessaire autour du dernier chmod, puisque le chmodage de certains fichiers spéciaux a échoué.
Vous pouvez aussi utiliser tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
et si vous voulez aussi voir le dossier, ajoutez un écho
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
Vous pouvez utiliser le script de bash suivant comme exemple. Veillez à lui donner des permissions d'exécution (755). Utilisez simplement ./autochmod.sh pour le répertoire courant, ou ./autochmod.sh <dir> pour en spécifier un autre.
#!/bin/bash
if [-e $1]; then
if [-d $1];then
dir=$1
else
echo "No such directory: $1"
exit
fi
else
dir="./"
fi
for f in $(ls -l $dir | awk '{print $8}'); do
if [-d $f];then
chmod 755 $f
else
chmod 644 $f
fi
done