Come ricodificare ricorsivamente tutte le directory tranne i file?


Risposte:


802

Per assegnare in modo ricorsivo alle directory i privilegi di lettura ed esecuzione:

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

Per assegnare in modo ricorsivo i privilegi di lettura dei file :

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

Oppure, 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)

Oppure, per ridurre la chmoddeposizione 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

7
I primi due esempi falliscono per directory con troppi file: -bash: /bin/chmod: Argument list too long. L'ultimo comando funziona con molti file, ma quando ne usi sudouno devi fare attenzione a metterlo prima di xargs invece di chmod:find /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755
— Agargara,

2
Inoltre, questi comandi sono comprensivi della dir di base. Quindi, nell'esempio sopra, dirverrà impostato anche su 755.
— CenterOrbit

2
chmod ... $(find /path/to/base/dir -type ...)non riesce per i nomi di file con spazi nel nome.
— Dan Dascalescu,

7
Penso che la versione più corretta (ma non più veloce) rispetto agli spazi e ai simboli nei nomi dei file e nel numero di file sia find /path/to/base/dir -type d -exec chmod 755 {} \;( find /path/to/base/dir -type f -exec chmod 644 {} \;).
— Peter K,

Nota che questo vale solo per il primo livello che può leggere. Dovrai eseguirlo più volte per approfondire la struttura delle directory.
— Henk Poley,

290

Un motivo comune per questo genere di cose è impostare le directory su 755 ma i file su 644. In questo caso c'è un modo leggermente più veloce finddell'esempio di Nik :

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

Senso:

  • -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 le maiuscole Xagiscono diversamente dalle lettere minuscole x. Nel manuale possiamo leggere:

I bit di esecuzione / ricerca se il file è una directory o uno 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 imposteranno solo se è già impostato per l'utente.


5
-R = ricorsivamente; u + rwX = Gli utenti possono leggere, scrivere ed eseguire; go + rX = group e altri possono leggere ed eseguire; go-w = group e altri non sanno scrivere
— släcker

23
Questo modello non risolverà la situazione quando qualcuno lo ha fatto chmod -R 777poiché l' +Xopzione non ripristinerà i bit di esecuzione esistenti sui file. L'uso di -x reimposta le directory e impedisce di scendere in esse.
— Andrew Vit,

3
@ ring0: non ho intenzione di rispondere alla domanda letteralmente come posato - Nik ha già fatto perfettamente. Sto indicando una soluzione più economica per il caso più comune. E sì, ottieni autorizzazioni diverse per file e directory con X, come spiegato nei commenti.
— bobince,

6
go+rX,go-w-> go=rXnon è vero?
— Pierre de LESPINAY,

5
È inoltre possibile utilizzare chmod u-x,u+Xin combinazione, ecc., Per rimuovere i bit di esecuzione per i file, ma aggiungerli per le directory.
— w0rp,

14

Se vuoi assicurarti che i file siano impostati su 644 e ci siano file nel percorso che hanno il flag di esecuzione, dovrai prima rimuovere il flag di esecuzione. + X non rimuove il flag di esecuzione dai file che già lo hanno.

Esempio:

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

Aggiornamento: questo sembra non riuscire perché la prima modifica (ugo-x) rende la directory non eseguibile, quindi tutti i file sottostanti non vengono modificati.


1
Questo funziona per me e non vedo perché non dovrebbe. (Certo, se lo facessi chmod -R ugo-x path, potrebbe essere un problema. Ma il comando completo eseguirà l'operazione chmod u+rwXsu ciascuna directory prima che tenti di discenderla.) Tuttavia, credo che chmod R u=rw,go=r,a+X pathsia sufficiente - ed è più breve.
— Scott,

Ho trovato che ha funzionato correttamente; non ci sono stati problemi con l'accesso alle directory
— Someone Somewhere,

4

Ho deciso di scrivere una piccola sceneggiatura per questo.

Script ricorsivo chmod 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 offre anche un po 'di flessibilità per le opzioni della riga di comando (imposta i permessi di directory e / o file, o esclude entrambi ripristina automaticamente tutto a 755-644). Verifica inoltre alcuni scenari di errore.

Ne ho anche scritto sul mio blog .


2

Per assegnare in modo ricorsivo alle directory i privilegi di lettura ed esecuzione:

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

Per assegnare in modo ricorsivo i privilegi di lettura dei file :

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

Meglio tardi che mai, lasciami aggiornare la risposta di Nik dal lato della correttezza. La mia soluzione è più lenta, ma funziona con qualsiasi numero di file, con qualsiasi simbolo nei nomi dei file e puoi eseguirla normalmente con sudo (ma attenzione che potrebbe scoprire file diversi con sudo).


Questo è un downgrade della risposta di Nik . Perché credi che ci sia qualcosa di sbagliato nella risposta di Nik?
— Scott,

@Scott, la risposta di Nik non riesce con (vey) un gran numero di file.
— Peter K,

Sono sicuro al 99% che ti sbagli. Potete fornire prove a sostegno del vostro reclamo?
— Scott,

Sì, sembra che mi sbagli davvero. trova ... + sembra spezzare la linea in più comandi, bella cattura!
— Peter K,

0

Prova questo script Python; non richiede la generazione di processi e fa solo due syscalls per file. A parte un'implementazione in C, sarà probabilmente il modo più veloce per farlo (ne avevo bisogno per riparare un filesystem di 15 milioni di file che erano tutti impostati su 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)

Nel mio caso, era necessario un tentativo / cattura attorno all'ultimo chmod, poiché alcuni file speciali non erano riusciti.


-1

Puoi anche usare tree:

tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'

e se vuoi vedere anche la cartella aggiungi un'eco

 tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'

@Scott 1) ​​Hai ragione circa + x Ho cambiato in 755; 2) 3) per risolvere questo ho messo il segnaposto in una virgoletta come questa '{}'
— Eduard Florinescu,

@Scott Sono d'accordo che questa non è la risposta migliore è anche lenta, ma partirà qui per scopi "didattici" anche i commenti spiegheranno ulteriormente, anche le persone possono conoscere i xargsproblemi. Le virgolette singole nei nomi dei file sono esse stesse un problema per molti comandi e script, per questo motivo ho elencato tutti i file contenenti virgolette singole e li ho rimossi (le virgolette intendo)
— Eduard Florinescu,

@Scott Sui miei sistemi ho cercato tutti i file che contenevano virgolette singole e ho sostituito le virgolette singole
— Eduard Florinescu,

@Scott Come risolveresti il ​​fatto che xargs non risolva correttamente le virgolette singole?
— Eduard Florinescu,


-2

È possibile utilizzare il seguente script bash come esempio. Assicurati di concedergli le autorizzazioni eseguibili (755). Basta usare ./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

2
Wow! Così tanti problemi! (1) Se $1non è null, ma non è il nome di una directory (ad esempio, è un refuso), dirviene impostato su .senza messaggio. (2) $1dovrebbe essere "$1"e $dirdovrebbe essere "$dir". (3) Non è necessario dirlo "./"; "."va bene (e, a rigor di termini, non hai bisogno di citazioni qui). (4) Questa non è una soluzione ricorsiva. (5) Sul mio sistema, ls -l … | awk '{ print $8 }'ottiene i tempi di modifica dei file. È necessario { print $9 }ottenere la prima parola del nome file. E anche allora, (6) questo non gestisce i nomi di file con spazi bianchi. ...
— Scott,

1
… E, ultimo ma non meno importante (∞) se questo script si trova nella directory corrente, sarà esso chmod stesso a 644, rendendosi quindi non eseguibile!
— Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.