Как рекурсивно chmod все каталоги, кроме файлов?
Как chmod 755 все каталоги, но не файл (рекурсивно)?
И наоборот, как chmod только файлы (рекурсивно), но не каталог?
9 ответов
Чтобы рекурсивно предоставить каталоги читать и выполнять привилегии:
find /path/to/base/dir -type d -exec chmod 755 {} +
Чтобы рекурсивно предоставить файлы привилегии чтения:
find /path/to/base/dir -type f -exec chmod 644 {} +
Или, если есть много объектов для обработки:
chmod 755 $(find /path/to/base/dir -type d)
chmod 644 $(find /path/to/base/dir -type f)
Или, чтобы уменьшить chmod
нерестится:
find /path/to/base/dir -type d -print0 | xargs -0 chmod 755
find /path/to/base/dir -type f -print0 | xargs -0 chmod 644
Общей причиной такого рода является установка каталогов на 755, но файлов на 644. В этом случае есть немного более быстрый путь, чем пример find
nik:
chmod -R u+rwX,go+rX,go-w /path
Значение:
-
-R
= рекурсивно; -
u+rwX
= Пользователи могут читать, писать и исполнять; -
go+rX
= группа, а другие могут читать и выполнять; -
go-w
= group и другие не могут писать
Важно отметить, что верхний регистр X
действует по-разному на нижний регистр x
. В руководстве мы можем прочитать:
Биты выполнения /поиска, если файл является каталогом, или любой из битов выполнения /поиска устанавливаются в исходном (немодифицированном) режиме.
Другими словами, chmod u + X в файле не будет устанавливать бит выполнения; и g + X будет устанавливать его только в том случае, если он уже установлен для пользователя.
Если вы хотите убедиться, что файлы установлены на 644, и есть файлы в пути, которые имеют флаг выполнения, вам сначала нужно будет удалить флаг выполнения. + X не удаляет флаг выполнения из файлов, которые уже имеют его.
Пример:
chmod -R ugo-x,u+rwX,go+rX,go-w path
Обновление: это не работает, потому что первое изменение (ugo-x) делает каталог неисполнимым, поэтому все файлы под ним не изменены.
Я решил написать маленький скрипт для этого сам.
Рекурсивный скрипт chmod для dirs и /или файлов â € "Gist
В основном это рекурсивный chmod, но также обеспечивает небольшую гибкость для параметров командной строки (устанавливает права на каталог и /или файлы, или исключает, что он автоматически сбрасывает все до 755-644). Он также проверяет несколько сценариев ошибок.
Я также написал об этом в своем блоге .
Чтобы рекурсивно предоставить каталоги читать и выполнять привилегии:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Чтобы рекурсивно предоставить файлы привилегии чтения:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Лучше поздно, чем никогда не позволять мне обновлять ответ nik на стороне правильности. Мое решение медленнее, но оно работает с любым количеством файлов, с любыми символами в именах файлов, и вы можете запускать его с помощью sudo обычно (но будьте осторожны, чтобы он мог обнаружить разные файлы с помощью sudo).
Попробуйте этот скрипт python; он не требует нереста процессов и делает только два системных вызовов для каждого файла. Помимо реализации в C, это, вероятно, будет самый быстрый способ сделать это (мне нужно было исправить файловую систему из 15 миллионов файлов, все из которых были установлены на 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)
В моем случае попытка try /catch потребовалась вокруг последнего chmod, так как chmodding некоторых специальных файлов не удалось.
Чтобы рекурсивно предоставить каталогам привилегии «читать» и «выполнять»:
find /directory-path -type d -exec sudo chmod 2775 {} +
Вы также можете использовать дерево tree
:
tree -faid /your_directory | xargs -L1 -I{} sudo chmod +x {}
В качестве примера можно использовать следующий сценарий bash. Обязательно предоставляйте ему права на выполнение (755). Просто используйте ./autochmod.sh для текущего каталога или ./autochmod.sh <dir> для указания другого.
#!/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