32

Is there some order of operations to rm? I performed rm on a large directory and am curious where I should look to see what might have been deleted. Does rm work on files first, then directories? Or is it based on some information in the inode table?

Specs: rm from GNU coreutils 8.22 system: Arch Linux running on a beagleboneblack filesystem operating on was an external Seagate HDD (ext4) using USB 2.0.

Backstory:

I was performing some directory cleanup and performed

cp -r A/ B/ C/ Dest/

Unwittingly, I followed that up with

rm -r A/ B/ C/ Dest/

when I meant to simply perform

rm -r A/ B/ C/

I caught this and hit Ctrl+C before too long had passed. Specifically, it was < 3 seconds as I was using the time command in conjunction with rm & cp. I went in and examined Dest/ expecting it to be non-existent, but lo and behold it was whole and appeared to not be affected. This is a bit surprising as A/ B/ C/ were quite small. Maybe 100–200 MB total. Dest/ however, is just shy of 1TB. Performing an ls on Dest/ showed that there were both files and directories at both ends of the alphabet (e.g. AFile.txt .... .... Zoo.txt).

Did I get lucky and cancelled the rm before it wrought havoc on my Dest/ directory? Is rm really that slow (thankfully!)?

If not, how does rm go about recursively removing things such that I can guess what might have been lost?

I'm not really expecting to recover what I might have lost, just curious what potentially was blown away.

1
36

rm -r works on each of its arguments in turn. If an argument is a directory, it lists the directory (with the opendir and readdir functions or some equivalent method), and operates on each entry in turn. If an entry is a directory, it explores that entry recursively.

This is exactly the same method that other applications use to traverse directories recursively — find, ls -Rf, etc.

The order of traversal is unpredictable. On most filesystems, the order is reproducible as long as no file is added, removed or renamed in the directory (the order could in theory be completely random and change every time, but I can't think of a filesystem where that happens). On a few filesystems, the order can in general be deduced from the file names or from the order in which the files were created or a combination of both, but you need to know the fine details of the filesystem, and it could vary depending on the driver version. The order of traversal isn't something you can rely on.

Note that ls or echo * do sort files in lexicographic order of their names. find and ls -f do not sort.

The one thing you can rely on is that the arguments are handled in order. So if C/ was still partially there, it would mean that Dest/ was untouched. If C/ is gone, you can get an idea of where files have been removed in Dest/ by checking the directory modification times and comparing them with the time C/ was deleted or the time the copy ended. The first file to be deleted could be a file directly in Dest/ or somewhere deep in the hierarchy depending on whether the first entry in Dest/ that rm happened to traverse was a directory or not.

The speed of rm is mostly a matter of how many files there are to delete. It takes a very large file to have a noticeable impact on the deletion time. The bulk of the work is deleting each directory entry in turn. The file's data isn't erased, erasing a file's content only requires to mark the blocks that it was using as free, which is relatively fast.

6
  • 2
    The -f option of ls is documented as being equivalent to -aU, where -a means list all files and -U means unsorted. I vaguely recall encountering a version of ls in which -f didn't work (I think it was defined to be something else) but -aU did. – G-Man Says 'Reinstate Monica' Oct 13 '14 at 16:33
  • 2
    @G-Man POSIX defines -f (as an XSI extension); it does indeed have other effects beyond unsorted. It goes back to V7, so you'd be hard-pressed to find an implementation without it apart from, strangely, BusyBox. -U for just unsorted is a GNU feature, I don't think it exists anywhere else. – Gilles 'SO- stop being evil' Oct 13 '14 at 17:36
  • @Tim No. You can test by running ls -U in a directory. This is the same order that rm -r would work in in that directory. Note that adding or removing a file can change the order of the other files. – Gilles 'SO- stop being evil' Mar 25 '15 at 1:27
  • Thanks. (1) "adding or removing a file can change the order of the other files.", so after accidental partial removal, ls -U doesn't help to find out if surviving dirs are untouched? (2) -U means "list entries in directory order". Does -U means the order of directory entries in the dir? – Tim Mar 25 '15 at 1:42
5

As Gilles says, you can't generally predict the order of deletions within a directory, only that the top-level directories will be processed in the order on the command line.

However, you're also guaranteed that it will delete directory hierarchies from the bottom up, because Unix only allows directories to be deleted if they're empty. So in order to delete a directory, it first has to remove everything in it. If it contains subdirectories, it has to remove their contents first, and so on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.