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

403982
Olivier Lalonde

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

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

532
Связанный: [Измените все разрешения для файлов и папок каталога на 644/755] (http://stackoverflow.com/q/18817744/55075) в SO kenorb 8 лет назад 0
Связано: [Изменить все разрешения для папок с помощью одной команды] (https://unix.stackexchange.com/q/349053/23408) в U & L. Scott 5 лет назад 0

8 ответов на вопрос

739
nik

Чтобы рекурсивно дать каталогам права на чтение и выполнение:

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 
Первые два примера не работают для каталогов со слишком большим количеством файлов: `-bash: / bin / chmod: список аргументов слишком длинный`. Последняя команда работает со многими файлами, но при использовании `sudo` нужно быть осторожным, помещая ее перед xargs вместо chmod:` find / path / to / base / dir -type d -print0 | sudo xargs -0 chmod 755 ` Agargara 6 лет назад 4
Также следует отметить, что эти команды * включены * из базового каталога. Таким образом, в приведенном выше примере, `dir` также будет установлен на 755. CenterOrbit 6 лет назад 2
`chmod ... $ (find / path / to / base / dir -type ...)` завершается ошибкой для имен файлов с пробелами в имени. Dan Dascalescu 6 лет назад 1
Я думаю, что наиболее правильной (но не самой быстрой) версией в отношении пробелов и символов в именах файлов и количестве файлов является `find / path / to / base / dir -type d -exec chmod 755 {} \;` (`find / путь / к / base / dir -type f -exec chmod 644 {} \; `). Peter K 6 лет назад 5
266
bobince

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

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

Имея в виду:

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

Здесь важно отметить, что прописные буквы Xдействуют не так, как строчные x. В руководстве мы можем прочитать:

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

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

-R = рекурсивно; u + rwX = Пользователи могут читать, писать и выполнять; go + rX = group и другие могут читать и выполнять; go-w = группа и другие не могут писать släcker 14 лет назад 4
Этот шаблон не исправит ситуацию, когда кто-то выполнил `chmod -R 777`, так как опция` + X` не сбрасывает существующие биты выполнения для файлов. Использование -x сбросит каталоги и предотвратит спуск в них. Andrew Vit 11 лет назад 22
Но как ваша команда отвечает на вопрос OP: установить разные ACL в зависимости от file / dir? Ваша команда установит ACL независимо от того, является ли это каталогом или файлом Ring Ø 11 лет назад 0
@ ring0: я не собираюсь отвечать на вопрос буквально, как задано - nik уже сделал это на отлично. Я указываю на более дешевое решение для наиболее распространенного случая. И да, вы получаете разные разрешения для файлов и каталогов с помощью `X`, как объяснено в комментариях. bobince 11 лет назад 2
`go + rX, go-w` ->` go = rX` не так ли? Pierre de LESPINAY 9 лет назад 5
`chmod -R u + rwX, g + rwX, o + rX *` значительно упростили мою жизнь при работе с fedora, у которой есть разрешения на обслуживание документов. Tiny Giant 9 лет назад 0
Вы также можете использовать `chmod ux, u + X` в комбинации и т. Д., Чтобы удалить биты выполнения для файлов, но добавить их для каталогов. w0rp 8 лет назад 4
12
mpolden

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

Пример:

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

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

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

I decided to write a little script for this myself.

Recursive chmod script for dirs and/or files — Gist

It basically does the recursive chmod but also provides a bit of flexibility for command line options (sets directory and/or file permissions, or exclude both it automatically resets everything to 755-644). It also checks for a few error scenarios.

I also wrote about it on my blog.

2
Peter K

Чтобы рекурсивно дать каталогам права на чтение и выполнение:

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

Чтобы рекурсивно дать файлам права на чтение:

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

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

Это *** понижение *** ответа [nik] (https://superuser.com/q/91935/150988#91938). Почему вы считаете, что с ответом Ника что-то не так? Scott 5 лет назад 0
@ Scott, ответ nik терпит неудачу с (очень) большим количеством файлов. Peter K 5 лет назад 0
I’m 99% sure that you’re mistaken. Can you provide any evidence to support your claim? Scott 5 лет назад 0
Да, похоже, я действительно неправ. найти ... +, кажется, разбить строку на несколько команд, хороший улов! Peter K 5 лет назад 0
0
mic_e

Try this python script; it requires no spawning of processes and does only two syscalls per file. Apart from an implementation in C, it will probably be the fastest way of doing it (I needed it to fix a filesystem of 15 million files which were all set to 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) 

In my case, a try/catch was required around the last chmod, since chmodding some special files failed.

-1
Eduard Florinescu

Вы также можете использовать 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' -- '{}' 
@ Скотт 1) Вы правы насчет + х, я изменил на 755; 2) 3) чтобы решить эту проблему, я поместил заполнитель в одинарную кавычку, например: «{}» Eduard Florinescu 5 лет назад 0
@ Scott Я согласен, что это не самый лучший ответ, и он слишком медленный, но он уйдет сюда для «дидактических» целей, комментарии будут объяснены далее, а также люди смогут узнать о проблемах с `xargs`. Одиночные кавычки в именах файлов сами по себе являются проблемой для многих команд и сценариев, поэтому я перечислил все файлы, содержащие одинарные кавычки, и удалил их (я имею в виду кавычки) Eduard Florinescu 5 лет назад 0
@Scott В моих системах я искал все файлы, которые содержали одинарные кавычки и заменил одинарные кавычки Eduard Florinescu 5 лет назад 0
@ Скотт Как бы вы исправили тот факт, что xargs неправильно решает одинарные кавычки? Eduard Florinescu 5 лет назад 0
Давайте [продолжим это обсуждение в чате] (https://chat.stackexchange.com/rooms/84264/discussion-between-eduard-florinescu-and-scott). Eduard Florinescu 5 лет назад 0
-2
user26528

Вы можете использовать следующий скрипт 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 ''); do if [ -d $f ];then chmod 755 $f else chmod 644 $f fi done 
Вот Это Да! Так много проблем! (1) Если `$ 1` не равно нулю, но не является именем каталога (например, является опечаткой), то для` dir` устанавливается значение `.` без сообщения. (2) `$ 1` должно быть` "$ 1" `и` $ dir` должно быть `" $ dir "`. (3) Вам не нужно говорить `" ./ "`; `". "` хорошо (и, строго говоря, здесь вам не нужны кавычки). (4) Это не рекурсивное решение. (5) В моей системе `ls -l… | awk '' `получает время модификации файлов '. Вам нужно ``, чтобы получить _ первое слово_ имени файла. И даже тогда (6) это не обрабатывает имена файлов с пробелами. ... Scott 9 лет назад 2
... И, наконец, что не менее важно (∞), если этот скрипт находится в текущем каталоге, он будет `chmod` _itself_ в 644, таким образом делая себя неисполнимым! Scott 9 лет назад 1

Похожие вопросы