Почему запуск «$ sudo chmod -R 664 . » приводит к отказу в доступе ко всем затронутым каталогам?

Почему запуск «$ sudo chmod -R 664 . » приводит к отказу в доступе ко всем затронутым каталогам?

У меня есть папка проекта, в которой беспорядочные разрешения на все файлы. У меня была плохая привычка устанавливать все на восьмеричные разрешения 777, потому что это решало все проблемы, не связанные с безопасностью. Затем загрузка FTP, файлы, созданные текстовыми редакторами и т. д., имеют свой собственный набор разрешений, что делает все беспорядок. Я решил взять себя в руки и начать использовать разрешения так, как они должны использоваться.

Я решил, что 664 — это хорошее значение по умолчанию для всех моих файлов и папок, и я просто удалю разрешения для других на личные файлы и добавлю +x для исполняемых файлов.

Однако во второй раз я изменил папку проекта на 664:

$ sudo chmod -R 664 .  
$ лс  
ls: невозможно открыть каталог .: Отказано в доступе  

Что для меня не имеет смысла. У меня есть права на чтение/запись, и я владелец папки проекта. Самая левая часть ls -lв моей папке проекта выглядит так:

-rw-rw-r-- 1 codemonkey codemonkey ...
drw-rw-r-- 5 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
drw-rw-r-- 3 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
-rw-rw-r-- 1 codemonkey codemonkey ...
drw-rw-r-- 4 codemonkey codemonkey ...
drw-rw-r-- 5 codemonkey codemonkey ...

Я предполагаю, что это как-то связано с правами доступа к каталогам, ночто?

решение1

Бит выполнения необходим для обхода каталога *nix. Вы не можете cdвойти в каталог, для которого у вас нет прав на выполнение, и это влияет на ряд утилит неочевидными способами, если им нужен контекст каталога. Рассмотрим:

$ cd /tmp
$ mkdir foo
$ echo baz > foo/bar
$ chmod a-x foo

# You can read the contents of the directory, but ls still complains. 
$ ls foo
ls: cannot access foo/bar: Permission denied
bar

# You can't read the file because you can't enter the directory.
$ cat foo/bar
cat: foo/bar: Permission denied

Причина всего этого в том, как работает stat(). Выдержка из man 2 stat:

Для самого файла никаких разрешений не требуется, но — в случае stat() и lstat() — требуется разрешение на выполнение (поиск) для всех каталогов в пути, ведущем к файлу.

Суть в том, что рекурсивный код chmodредко будет делать то, что вы ожидаете, и будет создавать хаос в разрешениях на чтение и выполнение каталогов, что может привести к неожиданным результатам, как у вас. Всегда рассматривайте разрешения каталогов отдельно от разрешений файлов для достижения наилучших результатов.

решение2

Вам необходимы разрешения на выполнение каталогов.

Учитывать

sudo find -type d -exec chmod +x {} +

Обновление: вот мое обоснование этого, на первый взгляд, странного использования разрешений на выполнение.

Unix (и, следовательно, Linux) в значительной степени рассматривает все как файлы. Это распространяется на диски и различные другие устройства. Это также включает каталоги.

Традиционные файловые системы Unix имеют набор разрешений, которые применяются к файлам. Поэтому разработчикам Unix пришлось найти что-то полезное для каждого бита разрешения, чтобы сделать его при применении к «файлу», который не был вашим обычным файлом данных.

Давайте рассмотрим каталоги. Сначала кажется разумным просто использовать разрешение на чтение, чтобы решить, может ли кто-то получить доступ к каталогу — например, чтобы создать список файлов в нем, их размеры, даты и т. д.

Однако предположим, что вы хотите, чтобы обычные пользователи могли запускать программы в /usr/local/bin, но не хотите, чтобы они могли рыться в /usr/local, чтобы посмотреть, что там. Если у вас есть только разрешение на чтение, вы не можете этого предотвратить.

Таким образом, в противном случае избыточное разрешение на выполнение использовалось для контроля того, разрешено ли вашей оболочке "обходить" каталог, под которым мы подразумеваем, не находить больше того, что необходимо для поиска и чтения деталей подкаталога как части пути. Это позволяет вам получить доступ к каталогу /usr/local только в той мере, в какой это необходимо для чтения содержимого /usr/local/bin.

Итак, +x для /usr/local означает, что вы можете запустить "/usr/local/bin/foo". Но +r для /usr/local означает, что вы можете узнать все, что находится в /usr/local, включая информацию о владельце, разрешениях для каждого файла, его размере и т. д.

Вышеизложенное основано на смутных воспоминаниях и догадках. Это может быть не совсем верно, но я считаю, что это дает разумное представление о том, почему «выполнить» означает «способный пройти».

Связанный контент