Jak przeskoczyć 755 we wszystkich katalogach, ale nie ma pliku (rekurencyjnie)?
I odwrotnie: jak chmod tylko pliki (rekurencyjnie), ale nie ma katalogu?
Jak przeskoczyć 755 we wszystkich katalogach, ale nie ma pliku (rekurencyjnie)?
I odwrotnie: jak chmod tylko pliki (rekurencyjnie), ale nie ma katalogu?
Odpowiedzi:
Aby rekurencyjnie nadać katalogom uprawnienia do odczytu i wykonywania:
find /path/to/base/dir -type d -exec chmod 755 {} +
Aby rekurencyjnie nadać plikom uprawnienia do odczytu:
find /path/to/base/dir -type f -exec chmod 644 {} +
Lub, jeśli istnieje 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 ograniczyć chmod
odradzanie:
find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
-bash: /bin/chmod: Argument list too long
. Ostatnie polecenie działa z wieloma plikami, ale podczas korzystania z sudo
nich należy uważać, aby umieścić je przed xargs zamiast chmod:find /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755
dir
zostanie również ustawiona wartość 755.
chmod ... $(find /path/to/base/dir -type ...)
kończy się niepowodzeniem dla nazw plików ze spacjami w nazwie.
find /path/to/base/dir -type d -exec chmod 755 {} \;
( find /path/to/base/dir -type f -exec chmod 644 {} \;
).
Typowym powodem tego rodzaju rzeczy jest ustawienie katalogów na 755, a plików na 644. W tym przypadku jest nieco szybszy sposób niż w find
przykładzie Nik :
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ćNależy tutaj zauważyć, że wielkie litery X
działają inaczej niż małe litery x
. W instrukcji 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 na pliku nie ustawi bitu wykonania; a g + X ustawi to tylko, jeśli jest już ustawione dla użytkownika.
chmod -R 777
ponieważ +X
opcja nie zresetuje istniejących bitów wykonania plików. Użycie -x spowoduje zresetowanie katalogów i zapobiegnie zejściu do nich.
X
, jak wyjaśniono w komentarzach.
go+rX,go-w
-> go=rX
prawda?
chmod u-x,u+X
w kombinacji itp., Aby usunąć bity wykonania dla plików, ale dodać je do katalogów.
Jeśli chcesz się upewnić, że pliki są ustawione na 644 i na ścieżce znajdują się pliki z flagą wykonania, najpierw musisz usunąć flagę wykonania. + X nie usuwa flagi wykonania z plików, które już ją mają.
Przykład:
chmod -R ugo-x,u+rwX,go+rX,go-w path
Aktualizacja: wydaje się, że kończy się to niepowodzeniem, ponieważ pierwsza zmiana (ugo-x) powoduje, że katalog jest niewykonalny, więc wszystkie pliki pod nim nie są zmieniane.
chmod -R ugo-x path
, może to być problem. Ale pełne polecenie wykona chmod u+rwX
każdy katalog przed próbą zejścia do niego.) Uważam jednak, że chmod R u=rw,go=r,a+X path
to wystarczy - i jest krótsze.
Postanowiłem napisać do tego mały skrypt.
Rekurencyjny skrypt chmod dla katalogó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
Zasadniczo robi rekurencyjny chmod, ale zapewnia także trochę elastyczności opcjom wiersza poleceń (ustawia uprawnienia do katalogu i / lub plików lub wyklucza oba, automatycznie resetuje wszystko do 755-644). Sprawdza także kilka scenariuszy błędów.
Pisałem również o tym na moim blogu .
Aby rekurencyjnie nadać katalogom uprawnienia do odczytu i wykonywania:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Aby rekurencyjnie nadać plikom uprawnienia do odczytu:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Lepiej późno niż nigdy nie pozwól mi zaktualizować odpowiedzi 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żesz normalnie uruchamiać go z sudo (ale uważaj, że sudo może odkryć różne pliki).
Wypróbuj ten skrypt Pythona; nie wymaga odradzania procesów i wykonuje tylko dwa wywołania systemowe na plik. Oprócz implementacji w C, będzie to prawdopodobnie najszybszy sposób na zrobienie tego (potrzebowałem go, aby naprawić system plików zawierający 15 milionów plików, które został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 wymagana była próba / catch wokół ostatniego chmod, ponieważ chmodding niektórych plików specjalnych nie powiodło się.
Możesz także użyć tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
a jeśli chcesz również wyświetlić folder, dodaj echo
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
xargs
problemach. Pojedyncze cytaty w nazwach plików same w sobie stanowią problem dla wielu poleceń i skryptów, dlatego wymieniłem wszystkie pliki zawierające pojedyncze cytaty i usunąłem je (mam na myśli cytaty)
Możesz użyć następującego skryptu bash jako przykładu. Pamiętaj, aby nadać mu uprawnienia do wykonywania (755). Wystarczy użyć ./autochmod.sh dla bieżącego katalogu lub ./autochmod.sh <katalog>, aby określić inny katalog.
#!/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
$1
nie ma wartości null, ale nie jest nazwą katalogu (np. Literówka), dir
zostaje ustawiony na .
brak wiadomości. (2) $1
powinno być "$1"
i $dir
powinno być "$dir"
. (3) Nie musisz mówić "./"
; "."
jest w porządku (i ściśle mówiąc, nie potrzebujesz tutaj cytatów). (4) To nie jest rozwiązanie rekurencyjne. (5) W moim systemie ls -l … | awk '{ print $8 }'
pobiera czasy modyfikacji plików. Musisz { print $9 }
uzyskać pierwsze słowo nazwy pliku. I nawet wtedy (6) nie obsługuje nazw plików z białą spacją. …
chmod
sam przejdzie na 644, przez co sam się nie wykona !