Почему rm может удалять файлы только для чтения?

93

Если я создаю файл, а затем изменяю его права доступа 444(только для чтения), как же его rmможно удалить?

Если я сделаю это:

echo test > test.txt
chmod 444 test.txt
rm test.txt

... rmспросит, хочу ли я удалить защищенный от записи файл test.txt. Я бы ожидал, что rmне смогу удалить такой файл и что мне придется сделать chmod +w test.txtсначала. Если я это сделаю, rm -f test.txtто rmудаляю файл, даже не спрашивая, даже если он доступен только для чтения.

Кто-нибудь может уточнить? Я использую Ubuntu 12.04 / bash.

Магнус
источник
Пояснение: я запускаю эти команды как обычный пользователь, а не как root.
Магнус

Ответы:

104

Все, что rmнужно - это разрешение на запись + выполнение в родительском каталоге. Права доступа к самому файлу не имеют значения.

Вот ссылка, которая объясняет модель разрешений более четко, чем я когда-либо мог:

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

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

Разрешение на выполнение требуется для каталога, чтобы иметь возможность CD в него (то есть, чтобы сделать некоторый каталог вашим текущим рабочим каталогом).

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

ire_and_curses
источник
2
Поэтому, если бы я хотел создать каталог, в котором некоторые файлы нельзя было бы удалить / изменить, не выполнив сначала команду chmod, а другие можно было бы свободно записывать, это было бы невозможно? Мне пришлось бы chmod каталог 555, что означало бы, что никакие файлы в каталоге не могут быть созданы или изменены.
Магнус
3
@Magnus - Конечно, ничто не мешает вам создать доступный для записи дочерний каталог внутри каталога только для чтения и хранить в нем свои записываемые файлы. Сам дочерний каталог не может быть удален, но его содержимое может.
ire_and_curses
7
Разве вы не можете привязать каталог, +tчтобы люди больше не могли изменять или удалять файлы в этом каталоге, которые им не принадлежат, даже если у них есть доступ для записи в каталог?
Шадур
3
@Magnus Если у вас есть root-доступ (включая sudo), вы можете использовать, chattrчтобы добавить неизменяемый флаг к файлам. Если нет, то ire_and_curses вполне корректен.
Джеймс О'Горман
6
Отказ от использования rm -f работает только до тех пор, пока я трезвый ... плюс, я понятия не имею, что могут делать или не делать сценарии с запаздывающим bash, которые я пишу
Magnus
53

Хорошо, согласно вашему комментарию к ire_and_curses, вы действительно хотите сделать некоторые файлы неизменяемыми. Вы можете сделать это с помощью chattrкоманды. Например:

например

$ cd /tmp
$ touch immutable-file
$ sudo chattr +i immutable-file

$ rm -f immutable-file
rm: remove write-protected regular empty file `immutable-file'? y
rm: cannot remove `immutable-file': Operation not permitted

$ mv immutable-file someothername
mv: cannot move `immutable-file' to `someothername': Operation not permitted

$ echo foo > immutable-file 
-bash: immutable-file: Permission denied

Вы не можете ничего сделать с неизменяемым файлом - вы не можете удалить его, отредактировать, перезаписать, переименовать, chmod или chown, или что-то еще. Единственное, что вы можете сделать с ним - это прочитать его (если позволяют разрешения unix) и (как root) chattr -iудалить неизменный бит.

Не все файловые системы поддерживают все атрибуты. AFAIK, immutable поддерживается всеми распространенными файловыми системами linux (в том числе ext2 / 3/4 и xfs. Zfsonlinux на данный момент вообще не поддерживает атрибуты)

саз
источник
3
это иногда полезно. Кстати, даже root не может изменять или удалять неизменяемый файл (не без предварительного удаления неизменяемого атрибута). также, кстати, используйте lsattrдля перечисления атрибутов.
Cas
2
+1 - я забыл об атрибутах и ​​был так занят, отвечая на буквальный вопрос о rmтом, что мне это даже не приходило в голову ...
ire_and_curses
2
Это зависит от файловой системы, и это может принести вам больше проблем, которые она решает.
Стефан Гименес
4
@Magnus: возможные проблемы включают в себя резервное копирование (не все утилиты резервного копирования будут создавать резервные копии атрибутов - на самом деле большинство не будет) и восстановление (если вы восстанавливаете в каталог, который уже содержит неизменяемый файл, некоторые программы будут рассматривать невозможность перезаписать этот файл как фатальная ошибка и прерывание). Кроме того, вы можете запутаться, если забудете, что сделали файл неизменным, и не можете понять, почему его нельзя удалить .... сообщение об ошибке «Операция не разрешена» - это то же сообщение об ошибке, которое вы видите в некоторых типах файловой системы. коррупция, которая может привести к потенциально опасной чрезмерной реакции.
Cas
1
Вы можете скопировать (cp) неизменный файл.
Осьминог
0

В одном ответе на этот вопрос утверждается, что вы можете удалить файл из каталога только в том случае, если у него есть только writeразрешение, что совершенно неправильно! просто попробуйте! Дайте каталогу только writeразрешение и попробуйте удалить, вы не можете!
Чтобы удалить файл внутри директории, вам нужны writeи executeразрешение на директорию.

Теперь вернемся к вопросу: чтобы удалить файл с помощью, rmвы просто удаляете его инодную информацию из каталога, то есть вы не являетесь shreddingего с диска. Если информация об узле файла не находится в каталоге, вы не можете получить к нему доступ (также потому, что вы не можете видеть ее, поскольку она не указана в родительском каталоге), то есть она удалена для вас.
Таким образом, чтобы удалить файл из каталога, все, что вам нужно, это разрешение на каталог; разрешения на этот файл не имеют значения

Эдвард Торвальдс
источник