Вопрос Как рекурсивно chmod все каталоги, кроме файлов?


Как chmod 755 все каталоги, но нет файла (рекурсивно)?

И наоборот, как chmod только файлы (рекурсивно), но не каталог?


517
2018-01-06 01:56


происхождения


Связанный: Измените права всех файлов и папок каталога на 644/755на SO - kenorb


ответы:


Рекурсивно дать каталоги привилегии чтения и выполнения:

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

720
2018-01-06 01:58



Первые два примера не работают для каталогов со слишком большим количеством файлов: -bash: /bin/chmod: Argument list too long, Последняя команда работает со многими файлами, но при использовании sudo нужно быть осторожным, чтобы поставить его перед xargs вместо chmod: find /path/to/base/dir -type d -print0 | sudo xargs -0 chmod 755 - Agargara
Также следует отметить, что эти команды включительно основного ребра. Итак, в приведенном выше примере, dir также будет установлено значение 755. - CenterOrbit
chmod ... $(find /path/to/base/dir -type ...) fail для имен файлов с пробелами в имени. - Dan Dascalescu
Я думаю, что самая правильная (но не самая быстрая) версия относительно пробелов и символов в именах файлов и количестве файлов find /path/to/base/dir -type d -exec chmod 755 {} \; (find /path/to/base/dir -type f -exec chmod 644 {} \;). - Peter K


Общей причиной такого рода является установка каталогов на 755, но файлов до 644. В этом случае есть несколько более быстрый путь, чем nik's find пример:

chmod -R u+rwX,go+rX,go-w /path

Имея в виду:

  • -R = рекурсивно;
  • u+rwX = Пользователи могут читать, писать и исполнять;
  • go+rX = группа и другие могут читать и выполнять;
  • go-w = группа и другие не могут писать

Важно отметить, что в верхнем регистре X действует по-другому в нижнем регистре x, В руководстве мы можем читать:

Биты выполнения / поиска, если файл является каталогом, или любой из битов выполнения / поиска устанавливаются в исходном (немодифицированном) режиме.

Другими словами, chmod u + X в файле не будет устанавливать бит выполнения; и g + X будет устанавливать его только в том случае, если он уже установлен для пользователя.


261
2018-01-06 03:22



-R = рекурсивно; u + rwX = Пользователи могут читать, писать и исполнять; go + rX = group и другие могут читать и исполнять; go-w = group и другие не могут писать - släcker
Этот шаблон не будет исправлять ситуацию, когда кто-то сделал chmod -R 777 поскольку +X опция не сбрасывает существующие биты выполнения в файлы. Использование -x сбрасывает каталоги и предотвращает попадание в них. - Andrew Vit
@ ring0: Я не собираюсь отвечать на вопрос буквально как поставленный - nik уже сделал это отлично. Я указываю более дешевое решение для наиболее распространенного случая. И да, вы получаете разные разрешения для файлов и каталогов с X, как объяснено в комментариях. - bobince
go+rX,go-w -> go=rX не так ли? - Pierre de LESPINAY
Вы также можете использовать chmod u-x,u+X в комбинации и т. д., чтобы удалить исполняемые биты для файлов, но добавить их для каталогов. - w0rp


Если вы хотите удостовериться, что файлы установлены на 644, и есть файлы в пути, которые имеют флаг выполнения, вам сначала нужно будет удалить флаг выполнения. + X не удаляет флаг выполнения из файлов, которые уже имеют его.

Пример:

chmod -R ugo-x,u+rwX,go+rX,go-w path

Обновление: кажется, что это сбой, потому что первое изменение (ugo-x) делает каталог неисследованным, поэтому все файлы под ним не изменяются.


12
2018-01-22 16:14



Это работает для меня, и я не понимаю, почему это не так. (Конечно, если бы вы просто chmod -R ugo-x path, это может быть проблемой. Но полная команда выполнит chmod u+rwX в каждом каталоге, прежде чем он попытается спуститься в него.) Однако я считаю, что chmod R u=rw,go=r,a+X path достаточно - и это короче. - Scott
Я нашел, что это сработало правильно; не было проблем с вводом справочников - Someone Somewhere


Я решил написать небольшой скрипт для этого сам.

Рекурсивный скрипт chmod для dirs и / или файлов - Gist

В основном это рекурсивный chmod, но также обеспечивает небольшую гибкость для параметров командной строки (устанавливает права на каталоги и / или файлы, или исключает, что он автоматически сбрасывает все до 755-644). Он также проверяет несколько сценариев ошибок.

Я также писал об этом в моем блоге,


4
2017-09-18 14:00





Рекурсивно дать каталоги привилегии чтения и выполнения:

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

Рекурсивно дать файлы привилегии чтения:

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

Лучше поздно, чем никогда не позволять мне обновлять ответ ника на стороне правильности. Мое решение медленнее, но оно работает с любым количеством файлов, с любыми символами в именах файлов, и вы можете запускать его с помощью sudo обычно (но будьте осторожны, чтобы он мог обнаружить разные файлы с помощью sudo).


3
2018-02-21 11:58





Попробуйте этот скрипт 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 некоторых специальных файлов не удалось.


0
2018-03-26 04:37





Вы также можете использовать tree:

tree -faid /your_directory | xargs -L1 -I{} sudo chmod +x {}

-1
2018-02-16 09:34





В качестве примера можно использовать следующий сценарий 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

-2
2018-01-29 11:56



Вау! Так много проблем! (1) Если $1 не является нулевым, но не является именем каталога (например, является опечаткой), затем dir получает . без сообщения. (2) $1 должно быть "$1" а также $dir должно быть "$dir", (3) Вам не нужно говорить "./"; "." (и, строго говоря, вам здесь не нужны кавычки). (4) Это не рекурсивное решение. (5) В моей системе, ls -l … | awk '{ print $8 }' получает время модификации файлов. Тебе нужно { print $9 } получить первое слово имя файла. И даже тогда (6) это не обрабатывает имена файлов с пробелом. ... - Scott
... И, последнее, но не менее важное (∞), если этот скрипт находится в текущем каталоге, он будет chmod  сам до 644, что делает себя не исполняемым! - Scott