Как rm -r выполняет рекурсивное удаление? В каком порядке?

30

Есть ли какой-то порядок операций rm? Я выполнил rmбольшой каталог, и мне любопытно, куда мне посмотреть, что могло быть удалено. Работает ли rmсначала с файлами, потом с каталогами? Или это основано на некоторой информации в таблице inode?

Спецификации: rm из системы GNU coreutils 8.22: Arch Linux, работающий на beagleboneblack файловой системе, работающей на внешнем жестком диске Seagate (ext4), использующем USB 2.0.

Предыстория:

Я выполнял некоторую очистку каталога и выполнил

cp -r A/ B/ C/ Dest/

Я невольно последовал за этим

rm -r A/ B/ C/ Dest/

когда я хотел просто выполнить

rm -r A/ B/ C/

Я поймал это и нажал Ctrl+, Cпрежде чем прошло слишком много времени. В частности, это было <3 секунды, когда я использовал timeкоманду вместе с rm& cp. Я вошел и исследовал, Dest/ожидая, что это не будет существовать, но вот, это было целое и, казалось, не было затронуто. Это немного удивительно, так как A/ B/ C/были довольно маленькими. Может быть, 100–200 МБ. Dest/однако, просто стесняется 1 ТБ. Выполнение lson Dest / показало, что на обоих концах алфавита есть файлы и каталоги (например, AFile.txt.... .... Zoo.txt).

Мне повезло, и я отменил действия rmдо того, как это нанесло ущерб моему каталогу Dest /? Это rmдействительно так медленно (к счастью!)?

Если нет, то как происходит rmрекурсивное удаление таких вещей, чтобы я мог догадаться, что могло быть потеряно?

Я не собираюсь возвращать то, что мог потерять, просто любопытно, что могло сорваться.

Н. Клостерман
источник

Ответы:

34

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

Это точно такой же метод , что и другие приложения используют для траверсы каталогов рекурсивно - find, ls -Rfи т.д.

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

Обратите внимание, что lsили echo *делайте сортировку файлов в лексикографическом порядке их имен. findи ls -fне сортировать.

Вы можете положиться только на то, что аргументы обрабатываются по порядку. Так что, если бы C/он все еще был частично, это означало бы, что Dest/он не тронут. Если C/это не так, вы можете получить представление о том, куда были удалены файлы, Dest/проверив время изменения каталога и сравнив их со временем C/удаления или временем окончания копирования. Первым удаляемым файлом может быть файл, находящийся непосредственно в Dest/иерархии или где-то глубоко в ней, в зависимости от того, была ли первая запись в Dest/том, что rmпроизошло, быть каталогом или нет.

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

Жиль "ТАК - прекрати быть злым"
источник
2
-fВариант lsдокументируется как эквивалент -aU, где -aсписок означает , что все файлы и -Uсредства без сортировки. Я смутно припоминаю, что столкнулся с версией, lsкоторая -fне работала (я думаю, она была определена как нечто иное), но работала -aU.
G-Man говорит: «Восстанови Монику»
2
@ G-Man POSIX определяет -f(как расширение XSI ); у него действительно есть другие эффекты помимо несортированного. Он восходит к V7, поэтому вам будет сложно найти реализацию без нее, кроме, как ни странно, BusyBox. -Uпросто несортированная функция GNU, я не думаю, что она существует где-то еще.
Жиль "ТАК - перестань быть злым"
@Tim Нет. Вы можете проверить, запустив ls -Uв каталоге. Это тот же порядок, который rm -rбудет работать в этом каталоге. Обратите внимание, что добавление или удаление файла может изменить порядок других файлов.
Жиль "ТАК - перестань быть злым"
Спасибо. (1) «добавление или удаление файла может изменить порядок других файлов», поэтому после случайного частичного удаления ls -Uне поможет выяснить, не сохранились ли сохранившиеся каталоги? (2) -U означает «список записей в порядке каталога». -U означает порядок записей каталога в каталоге?
Тим
5

Как говорит Жиль, в общем случае вы не можете предсказать порядок удаления в каталоге, только то, что каталоги верхнего уровня будут обрабатываться в порядке, указанном в командной строке.

Однако вы также гарантируете, что он будет удалять иерархии каталогов снизу вверх, потому что Unix позволяет удалять каталоги только в том случае, если они пусты. Таким образом, чтобы удалить каталог, он должен сначала удалить все, что в нем. Если он содержит подкаталоги, он должен сначала удалить их содержимое и так далее.

Barmar
источник