4

After a mistype in a path when using cp, I seem to have accidentally copied the folder in to itself recursively, and now I can't delete that folder using rm -rf, or the Trash in Mac OS X Finder. The file is located on the startup (therefore HFS+J) disk.

The output from rm -rf is just Directory not empty repeated, like so:

rm: o/old/old/old/old/old/old/old/old: Directory not empty
rm: o/old/old/old/old/old/old/old: Directory not empty
rm: o/old/old/old/old/old/old: Directory not empty
rm: o/old/old/old/old/old: Directory not empty
rm: o/old/old/old/old: Directory not empty
rm: o/old/old/old: Directory not empty
rm: o/old/old: Directory not empty
rm: o/old: Directory not empty
rm: o: Directory not empty

What do I do to delete this folder?

I've tried renaming the first folder, as you can see, to shorten down the file path. The folder moves in to the Trash fine, but won't delete because of the following alert dialog:

The operation can’t be completed because the item is in use.
  • Try lsof o to see who is using your directory o. Then you can see what to close. Probably you have open a terminal in that directory, and/or you start some program from that directory. – Hastur Jun 20 '15 at 20:49
  • lsof o returns nothing, @Hastur – galexite Jun 23 '15 at 17:03
  • fuser o returns o: – galexite Jun 23 '15 at 17:04
4

Try

find o -delete

or

find o -depth -delete

-depth tells find to go to the deepest part of the directory tree first, and then work its way back up.  The man page says, "Use of -delete automatically turns on the -depth option."  If your version of find doesn't support -delete, try

find o -depth -exec rm -rf {} ";"
| improve this answer | |
  • Thanks for the suggestion, but unfortunately, it doesn't work: No space left on device – galexite Jun 23 '15 at 16:47
  • Strangely, df -h returns 15Gi free – galexite Jun 23 '15 at 16:48
  • That doesn't make a lot of sense; these commands shouldn't be writing anything to the filesystem.  (To split hairs; delete / rm / unlink will overwrite directory entries with nuls, and modify the free list to add the deallocated blocks to it, but it shouldn't be doing anything that should be trying to allocate free blocks from the free list.)  One explanation is that find needs to write a temporary file to save the directory structure of your "o" directory tree as it reads it.  Check df -h /tmp. – Scott Jun 23 '15 at 22:56
  • I'm afraid it is the same response from df -h – galexite Jun 24 '15 at 17:28
  • Well, actually, it's 11 Gi, but that's because I've been using my computer since, but still – galexite Jun 24 '15 at 17:29
2

Well, I just had the very same problem. I solved it by shortening the name of every single one of the nested directories.

Since it is a one time problem, I did not try to come up with any smart scripting magic. I just wrote

for FILE in $(ls); do mv $FILE a; cd a; done

in a shell, then hit the up arrow to call the command again, and return. With one finger on each key, I just repeated the two keystrokes quickly until the deepest directory. Then cd ~ and cd to the root of the faulty tree. A regular rm -r now got the job done.

| improve this answer | |
  • I did try this. I set all the directories' names to 'o', but to no avail: they still would not delete. This is a good idea though and worth trying out if you do ever encounter such an issue. – galexite Oct 5 '15 at 17:26
  • I too did an accidentally 'cp -R'. The rm command was failing on a file further down in the directory tree because of the nested paths. I had to do rm -rf old/ 2>&1 | less to find how deep the file was. Then I ran this for loop a number of times to shorten the path enough to delete the files. Thanks. – Bradley M Handy Nov 9 '15 at 18:58
1

If you get it it's obvious. Because you can't recurse deep down, you should move the directory which is one level deeper just one level up. After that a directory with depth "one" remains which can be deleted.

Lets assume you have an "infinite" directory a/a/a/a/a/a/a/....

then you do:

mv a/a b
rm -r a
mv b/a a
rm -r b

Repeat until no directory is left over.

The following script does it: (you have to press ctrl-c after it finishes)

while [ true ]; do mv a/a b; rm -r a; mv b/a a; rm -r b; done

Because the names are identical the scripts 'flips' between two temporary names.

| improve this answer | |

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.