У меня есть папка проекта, в которой беспорядочные разрешения на все файлы. У меня была плохая привычка устанавливать все на восьмеричные разрешения 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, включая информацию о владельце, разрешениях для каждого файла, его размере и т. д.
Вышеизложенное основано на смутных воспоминаниях и догадках. Это может быть не совсем верно, но я считаю, что это дает разумное представление о том, почему «выполнить» означает «способный пройти».