Jak rekurencyjnie chmodować wszystkie katalogi z wyjątkiem plików?
Jak chmodować 755 wszystkie katalogi, ale bez pliku (rekurencyjnie) ?
Jak odwrotnie, jak chmodować tylko pliki (rekurencyjnie), ale bez katalogu ?
Jak chmodować 755 wszystkie katalogi, ale bez pliku (rekurencyjnie) ?
Jak odwrotnie, jak chmodować tylko pliki (rekurencyjnie), ale bez katalogu ?
Aby powtarzalnie nadawać katalogi odczytywać i wykonywać uprawnienia:
find /path/to/base/dir -type d -exec chmod 755 {} +
Aby powtarzalnie nadawać pliki odczytywać uprawnienia:
find /path/to/base/dir -type f -exec chmod 644 {} +
lub, jeśli jest wiele obiektów do przetworzenia:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
lub, aby zmniejszyć chmod
tarło:
find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
Częstym powodem tego typu rzeczy jest ustawienie katalogów na 755 ale plików na 644. W tym przypadku jest nieco szybszy sposób niż w przykładzie Nik’s find
:
chmod -R u+rwX,go+rX,go-w /path
Znaczenie:
-R
= rekurencyjnie; u+rwX
= użytkownicy mogą czytać, pisać i wykonywać; go+rX
= grupa i inni mogą czytać i wykonywać; go-w
= grupa i inni nie mogą pisać Ważną rzeczą, którą należy tutaj zauważyć jest to, że duże litery X
działają inaczej niż małe x
. W podręczniku możemy przeczytać:
Bity wykonania/wyszukiwania jeśli plik jest katalogiem lub którykolwiek z bitów wykonania/wyszukiwania jest ustawiony w oryginalnym (niezmodyfikowanym) trybie.
Innymi słowy, chmod u+X w pliku nie ustawi bitu wykonania; a g+X ustawi go tylko jeśli jest już ustawiony dla użytkownika.
Jeśli chcesz się upewnić, że pliki są ustawione na 644 i w ścieżce znajdują się pliki, które mają flagę wykonania, będziesz musiał najpierw usunąć flagę wykonania. +X nie usuwa flagi wykonawczej z plików, które już ją mają.
Przykład:
chmod -R ugo-x,u+rwX,go+rX,go-w path
Update: wydaje się to nieudane, ponieważ pierwsza zmiana (ugo-x) czyni katalog niewykonalnym, więc wszystkie pliki pod nim nie są zmieniane.
Zdecydowałem się napisać do tego mały skrypt. Rekursywny skrypt chmod dla dirsów i/lub plików - 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
W zasadzie robi on rekurencyjny chmod, ale również zapewnia odrobinę elastyczności dla opcji linii poleceń (ustawia uprawnienia do katalogów i/lub plików, lub wyklucza oba, automatycznie resetuje wszystko do 755-644). Sprawdza również kilka scenariuszy błędów.
Napisałem o tym również na moim blogu .
Aby powtarzalnie nadawać katalogi uprawnienia do odczytu i wykonania:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Aby powtarzalnie nadawać pliki uprawnienia do odczytu:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Lepiej późno niż nigdy nie pozwolić mi uaktualnić odpowiedź nik po stronie poprawności. Moje rozwiązanie jest wolniejsze, ale działa z dowolną liczbą plików, z dowolnymi symbolami w nazwach plików, i można je uruchomić z sudo normalnie (ale uważaj, że może odkryć różne pliki z sudo).
Spróbuj tego skryptu Pythona; nie wymaga on tarła procesów i wykonuje tylko dwa syscale w jednym pliku. Poza implementacją w C, będzie to prawdopodobnie najszybszy sposób (potrzebowałem go do naprawienia systemu plików 15 milionów plików, które były ustawione na 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)
W moim przypadku, próba/łapanie było wymagane wokół ostatniego chmoda, ponieważ chmodding niektórych specjalnych plików nie powiodło się.
Możesz również użyć tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
i jeśli chcesz również zobaczyć folder dodaj echo
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
Jako przykład można użyć następującego skryptu bash. Należy nadać mu uprawnienia wykonywalne (755). Po prostu użyj ./autochmod.sh dla bieżącego katalogu, lub ./autochmod.sh <dir> aby określić inny.
#!/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