Come chmodare ricorsivamente tutte le directory tranne i file?
Come chmod 755 tutte le directory ma nessun file (ricorsivamente) ?
Inversamente, come chmod solo i file (ricorsivamente) ma nessuna directory ?
Come chmod 755 tutte le directory ma nessun file (ricorsivamente) ?
Inversamente, come chmod solo i file (ricorsivamente) ma nessuna directory ?
Per assegnare ricorsivamente directory privilegi di lettura e di esecuzione:
find /path/to/base/dir -type d -exec chmod 755 {} +
Per assegnare ricorsivamente file privilegi di lettura:
find /path/to/base/dir -type f -exec chmod 644 {} +
O, se ci sono molti oggetti da elaborare:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
O, per ridurre chmod
la deposizione delle uova:
find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
Una ragione comune per questo genere di cose è quella di impostare le directory a 755 ma i file a 644. In questo caso c'è un modo leggermente più veloce dell'esempio di nik find
:
chmod -R u+rwX,go+rX,go-w /path
``` &001
Significato:
- `-R` = ricorsivamente;
- `u+rwX` = gli utenti possono leggere, scrivere ed eseguire;
- `go+rX` = gruppo e altri possono leggere ed eseguire;
- `go-w` = gruppo e altri non possono scrivere
La cosa importante da notare qui è che il maiuscolo `X` agisce in modo diverso dal minuscolo `x`. Nel manuale possiamo leggere:
> I bit di esecuzione/ricerca se il file è una directory o uno qualsiasi dei bit di esecuzione/ricerca sono impostati nella modalità originale (non modificata).
In altre parole, chmod u+X su un file non imposterà il bit di esecuzione; e g+X lo imposterà solo se è già impostato per l'utente.
Se si vuole essere sicuri che i file siano impostati su 644 e ci sono file nel percorso che hanno il flag di esecuzione, si dovrà prima rimuovere il flag di esecuzione. +X non rimuove il flag di esecuzione dai file che lo hanno già.
Esempio:
chmod -R ugo-x,u+rwX,go+rX,go-w path
``` &001
Update: questo sembra fallire perché la prima modifica (ugo-x) rende la directory non eseguibile, quindi tutti i file sotto di essa non vengono modificati.
Ho deciso di scrivere io stesso un piccolo script per questo. script chmod ricorsivo per dirs e/o file - 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
Fondamentalmente fa il chmod ricorsivo ma fornisce anche un po’ di flessibilità per le opzioni a riga di comando (imposta i permessi di directory e/o file, o esclude entrambi automaticamente resetta tutto a 755-644). Controlla anche alcuni scenari di errore.
Ne ho anche scritto sul mio blog .
Per dare ricorsivamente directories privilegi di lettura e di esecuzione:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Per dare ricorsivamente file privilegi di lettura:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Meglio tardi che non mi lasci mai aggiornare la risposta di nik sul lato della correttezza. La mia soluzione è più lenta, ma funziona con qualsiasi numero di file, con qualsiasi simbolo nei nomi dei file, e si può eseguire normalmente con sudo (ma attenzione che potrebbe scoprire diversi file con sudo).
Provate questo script pitone; non richiede la riproduzione di processi e fa solo due syscalls per file. A parte un'implementazione in C, sarà probabilmente il modo più veloce per farlo (mi serviva per riparare un filesystem di 15 milioni di file che erano tutti impostati a 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)
``` &001
Nel mio caso, è stata necessaria una prova/catch intorno all'ultimo chmod, dato che chmodare alcuni file speciali non ha funzionato.
È possibile utilizzare anche tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
e se si desidera visualizzare anche la cartella aggiungere un eco
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
Si potrebbe usare il seguente script bash come esempio. Assicuratevi di dargli i permessi eseguibili (755). Utilizzare semplicemente ./autochmod.sh per la directory corrente, o ./autochmod.sh <dir > per specificarne una diversa.
#!/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