Почему инструменты любят cp
и rm
обрабатывают каталоги отдельно от обычных файлов? Они оба требуют, чтобы пользователь явно указал, что она хочет рекурсивное поведение, иначе они вообще не будут иметь дело с каталогами.
Мое первое взаимодействие (некоторое время назад) с компьютерами происходило в среде Windows / GUI / point-and-click / drag-and-drop, и всегда казалось естественным, что эти операции будут вести себя одинаково, независимо от цели.
Такое поведение особенно расстраивает меня, когда я даю команды с подстановочными знаками. Что если я хочу удалить все в каталоге ( *
), кроме непустых подкаталогов ?
Я могу только представить, что это какая-то функция безопасности, которая не позволяет пользователю выстрелить себе в ногу, но это противоречит моему пониманию некоторых принципов Unix:
- Unix обычно не защищает пользователя от себя. Он всегда предполагал, что пользователь знает, что она делает.
- Для Unix все это файл. Разве каталог не просто еще один файл? Почему к ним относятся по-разному?
Мои вопросы:
- Это поведение обусловлено техническими ограничениями или это осознанный выбор?
И в случае последнего,
- Есть ли исторические описания причин, которые мотивировали этот выбор?
rm
крайней мере, если вы хотите, чтобы игнорировать разницу между файлами и каталогами, вы можете поместить в вашем~/.bashrc
файле:alias rm='rm -r'
.Ответы:
Почему Дероберт почему для программы Unix mv не нужна опция -R (рекурсивная) для каталогов, а для cp она нужна? в основном отвечает на ваш вопрос: копирование или удаление обычного файла отличается от выполнения той же операции с каталогом, потому что для каталога вам нужно обработать все содержащиеся в нем файлы. Следовательно операция в корне отличается.
Также стоит отметить, что есть специальная утилита,
rmdir
которая может работать только с пустыми каталогами. Без проверки фактов это приводит к выводу, что, возможно, первоначальноrm
было возможно удалить только не-каталоги, а глубокое удаление должно было быть достигнуто путем рекурсивного использования,rm
чтобы очистить каталоги, а затемrmdir
удалить их.источник
rmdir
также имя системного вызова, который использовался для удаления каталога. Каталог должен быть пустым для системного вызова, а утилита с таким же именем просто "front-end", аналогичноunlink
команде и утилите.rm
возможно, вообще не удалось удалить каталоги (потому что утилиты командной строки часто являются просто относительно простыми обертками вокруг системных вызовов).rm
безусловно, не просто оболочка (он может одновременно удалять файлы mroe и каталоги). Если вам не нравится давать ему эту-r
опцию, используйте псевдонимы вашей оболочки или создайте свою собственную обертку, которая поместит ее на место (что будет медленнее, но не зависит от используемой вами оболочки).В некоторых версиях UNIX man-страница rm определяет ее как команду для удаления связи с файлом.
В UNIX файлы - это объекты в файловой системе, называемые Inodes, без имен или расположения, кроме идентификатора в файловой системе. Их имена являются ссылками на них в различных каталогах, которые представляют собой тип файла, который индексирует файлы (или каталоги, поскольку они являются файлами), которые перечислены в нем.
При отмене связывания файла счетчик ссылок файла уменьшается, а когда он достигает 0, он фактически удаляется, поскольку файловая система помечает его как свободный, а его блоки / экстенты также помечаются как свободные.
Если у вас была возможность создать каталог без предварительного отсоединения файлов внутри него, вы достигнете точки, когда у вас есть inode-ы, на которые есть ссылки в вашей файловой системе, но к которым нельзя получить доступ никакими обычными способами.
Поскольку существует ссылка на них в соответствии с их количеством ссылок, они не помечаются как удаленные и становятся потерянными файлами.
Это становится еще более сложным, когда потерянные «файлы» являются каталогами, и поэтому увеличивает потенциальный объем потерянного хранилища в файловой системе.
Таким образом, rm -r был добавлен в качестве функции, облегчающей жизнь пользователей UNIX, за счет стандартного «духа UNIX», поскольку он более сложен, чем классические утилиты UNIX, так как он спускается в каталоги и удаляет файлы внутри,
Кроме того, в ранние времена UNIX системы не имели большого объема памяти, а отображение рекурсивной структуры каталога приводило к снижению производительности, и иногда было невозможно обойтись без разделения работы.
cp, читает файл и копирует его, блок за блоком. Если бы он копировал каталог так же, как и файл, он добавил бы ссылки на файлы внутри, не увеличивая их счетчик ссылок, что могло бы привести к несогласованности данных (при чтении / записи в инод, чьи блоки помечены как свободные с момента их исходный индекс был удален), потерянные данные - поскольку удаление последней (известной) ссылки на файл может привести к повторному использованию его номера индекса.
Для группы tl; dr:
каталоги в UNIX - это тип файла, это правда, но поскольку информация в них обрабатывается системой по-разному, так как это метаданные файловой системы, команды, управляющие файлами, не могут работать с каталогами без изменить их поведение, чтобы манипулировать зависимыми метаданными.
источник