Почему рекурсия не идет вверх с rm?

13

Меня интересует направление рекурсии вообще и т. Д.

rm рекурсия работает только правильно?

Запуск: sudo rm -R *.QTFSудалит все файлы * .QTFS в текущем каталоге и его дочерних элементах, правильно?

текущий каталог, выдаваемые ls -lhaтакже содержит .и ..ссылки на отсутствие лучшего слова, так почему бы не рекурсии следовать этим вверх в дереве каталогов? Есть ли предел искусственного на ют приложения, или .и ..не реальные вещи?


источник
5
Потому что корень и безумие, таким образом, ложь ...
Джейсонвриан
1
Ну, для интересного анекдота ... Я однажды запустил rm -rf в некоторых невинных папках, чтобы, к моему ужасу, обнаружить, что у пользователя есть жесткие связи там с очень важным апстримом, который затем перешел к rm. Да, у меня были текущие резервные копии, и никакие данные не были потеряны, но пусть это будет предостерегающая история ... :-)
Брайан Ноблаух
@BrianKnoblauch, какой вред можно нанести, удалив жесткую ссылку? Я не
Алексей
@Alexey Дело в том, что сама жесткая ссылка не была удалена. Она вернулась в жестко связанный каталог, который был связан с более высокой точкой в ​​файловой системе, поэтому начал есть все данные ...
Брайан

Ответы:

18

rm рекурсия работает только правильно?

rm -r x yудалит xи yи все внутри них (если они каталоги), но не их родителей или что-то вне их.

Запуск: sudo rm -R *.QTFSудалит все файлы * .QTFS в текущем каталоге и его дочерних элементах, правильно?

Нет. Он удалит все названные файлы *.QTFS, все файлы, которые рекурсивно находятся в вызываемых каталогах*.QTFS , и сами эти каталоги. Если вы хотите другое поведение удаления, используйте find -delete.

текущий каталог, выдаваемые ls -lhaтакже содержит .и ..ссылки на отсутствие лучшего слова, так почему бы не рекурсии следовать этим вверх в дереве каталогов? Есть ли предел искусственного на ют приложения, или .и ..не реальные вещи?

Это искусственный предел rm.

Хотя на самом деле это не так уж и искусственно - это единственный способ, которым он может когда-либо работать. Если rmперейти по родительским ..ссылкам, каждый из rm -rних удалит все файлы в системе, следуя всем ..ссылкам вплоть до /. rmвидит ..и .записи в каждой директории , когда он перечисляет содержимое, и явно пренебрегает их по этой причине.

Вы можете попробовать это сами, на самом деле. Выполните, rm -r .и большинство rmреализаций откажутся действовать, явно сообщив об ошибке:

$ rm -r .
rm: refusing to remove ‘.’ or ‘..’ directory: skipping ‘.’

(это сообщение от GNUrm ; другие похожи). Когда он встречает эти записи неявно, а не как явные аргументы, он просто игнорирует их и продолжает работу. Такое поведение требуется POSIX . В GNU rmи многих BSD он автоматически предоставляется fts_readсемейством функций обхода иерархии.

или .и ..не настоящие вещи?

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

Майкл Гомер
источник
Для тех, кто ищет доказательства (или просто заинтересован), посмотрите, как это реализовано в GNU coreutils .
Крис Хейс
@ChrisHayes Эквивалентная ссылка на gitweb есть в ответе. Реальный рекурсивный случай в fts_readреализации, однако, только для аргументов командной строки.
Майкл Гомер
@MichaelHomer Ого, так и есть. Этот цвет ссылки не выделяется на этой схеме SE. Моя ошибка.
Крис Хейс
2
Этот ответ правильный, но также немного неточный. rmдаже не видит, *.QTFSпотому что он развернут глобально в имена файлов с помощью bash, прежде чем вызывается двоичный файл rm. Ответ @ tobyink отмечает это.
Daenyth
Как примечание, эти .и ..особые случаи поведения, как говорят, являются причиной существования
dotfiles
5

Помимо того, что написал Майкл Гомер, есть еще один фактор, который затрудняет случайный возврат в родительский каталог.

Зайдите в свой домашний каталог и введите что-то вроде:

echo *s*

Вы увидите, что он показывает список файлов и каталогов, содержащих букву «s». Однако файлы, начинающиеся с начальной точки, не отображаются. Чтобы показать их, вы можете использовать:

echo .*s*

Это потому, что оболочка отказывается расширяться, *чтобы охватить ведущую точку. Это означает, что:

rm -fr *

Не вернется в ...

tobyink
источник