Как chmod 755 все каталоги, но нет файла (рекурсивно)?
И наоборот, как chmod только файлы (рекурсивно), но без каталога?
Как chmod 755 все каталоги, но нет файла (рекурсивно)?
И наоборот, как chmod только файлы (рекурсивно), но без каталога?
Чтобы рекурсивно дать каталогам права на чтение и выполнение:
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
Ника:
chmod -R u+rwX,go+rX,go-w /path
Имея в виду:
-R
= рекурсивно;u+rwX
= Пользователи могут читать, писать и выполнять;go+rX
= group и другие могут читать и выполнять;go-w
= группа и другие не могут писатьЗдесь важно отметить, что прописные буквы X
действуют иначе, чем строчные буквы x
. В руководстве мы можем прочитать:
Биты выполнения / поиска, если файл является каталогом, или любой из битов выполнения / поиска установлены в исходном (неизмененном) режиме.
Другими словами, chmod u+X в файле не устанавливает бит выполнения; и g+X установит его, только если он уже установлен для пользователя.
Если вы хотите убедиться, что для файлов установлено значение 644, и в пути есть файлы с флагом выполнения, вам сначала нужно будет удалить флаг выполнения. +X не удаляет флаг выполнения из файлов, у которых он уже есть.
Пример:
chmod -R ugo-x,u+rwX,go+rX,go-w path
Обновление: кажется, что это не сработало, потому что первое изменение (ugo-x) делает каталог неисполнимым, поэтому все файлы под ним не изменяются.
Я решил написать небольшой сценарий для этого сам.
Рекурсивный скрипт chmod для директорий и / или файлов - Gist
Он в основном делает рекурсивный chmod, но также обеспечивает некоторую гибкость для параметров командной строки (устанавливает права доступа к каталогу и / или файлу или исключает оба, он автоматически сбрасывает все до 755-644). Он также проверяет несколько сценариев ошибок.
Я также написал об этом в своем блоге.
Чтобы рекурсивно дать каталогам права на чтение и выполнение:
find /path/to/base/dir -type d -exec chmod 755 {} \;
Чтобы рекурсивно дать файлам права на чтение:
find /path/to/base/dir -type f -exec chmod 644 {} \;
Лучше поздно, чем никогда, позвольте мне обновить ответ Ника на стороне правильности. Мое решение медленнее, но оно работает с любым количеством файлов, с любыми символами в именах файлов, и вы можете запустить его с помощью 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)
В моем случае попытка / отлов потребовалась для последнего chmod, так как chmodding некоторых специальных файлов не удался.
Вы также можете использовать tree
:
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1"' -- '{}'
и если вы хотите также просмотреть папку, добавьте эхо
tree -faid /your_directory | xargs -L1 -I{} bash -c 'sudo chmod 755 "$1" && echo$1' -- '{}'
Вы можете использовать следующий скрипт 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