it-swarm-eu.dev

Come ricodificare in modo ricorsivo tutte le directory tranne i file?

Come chmod 755 tutte le directory ma nessun file (in modo ricorsivo)?

Inversamente, come modificare solo i file (in modo ricorsivo) ma nessuna directory?

555
Olivier Lalonde

Per dare ricorsivamente directory leggi ed eseguire i privilegi:

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

Per dare ricorsivamente i privilegi files read:

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 chmod spawning:

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

Un motivo comune per questo tipo di cose è impostare le directory su 755 ma i file su 644. In questo caso c'è un modo leggermente più rapido rispetto all'esempio find 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 = il gruppo e gli altri non possono scrivere

La cosa importante da notare qui è che X in maiuscolo agisce diversamente con x in caratteri minuscoli. 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.

281
bobince

Se vuoi assicurarti che i file siano impostati su 644 e che ci siano dei file nel percorso con il flag di esecuzione, dovrai 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

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

13
mpolden

Ho deciso di scrivere una piccola sceneggiatura per questo me stesso.

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 della riga di comando (imposta le autorizzazioni di directory e/o file, oppure esclude entrambi ripristina automaticamente tutto a 755-644). Controlla anche alcuni scenari di errore.

Ho anche scritto su di esso sul mio blog .

4
francisbyrne

Per dare ricorsivamente directory leggi ed eseguire i privilegi:

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

Per dare ricorsivamente i privilegi files read:

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

Meglio tardi che non permettermi di aggiornare la risposta di Nikke sul lato della correttezza. La mia soluzione è più lenta, ma funziona con qualsiasi numero di file, con qualsiasi simbolo nei nomi dei file, ed è possibile eseguirlo normalmente con Sudo (ma attenzione che potrebbe scoprire diversi file con Sudo).

2
Peter K

Prova questo script python; non richiede generazione di processi e fa solo due syscalls per file. A parte un'implementazione in C, probabilmente sarà il modo più veloce di farlo (ne avevo bisogno per sistemare 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, è stato richiesto un try/catch attorno all'ultimo chmod, dato che chmodding alcuni file speciali non è riuscito.

0
mic_e