Cannot cleanup OS X trash

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.

Analogous to our "confdir-14B--" the following script works. (you have to press ctrl-c after it finishes)

while [ true ]; do mv confdir-14B---/confdir-14B--- b; rm -r confdir-14B---; mv b/confdir-14B--- confdir-14B---; rm -r b; done

Because the names are identical the scripts 'flips' between the original directory name and a temporary name. That is why two passes are needed.


Just happened this to me today, e.g. in my ~/.Trash/rcs-5.9.4/ i found many confdir-14B--- recursively, e.g. confdir-14B---/confdir-14B---/confdir-14B---/...

Because the simple find . -depth ... or the rm -r doesn't works, created the following shell script, which removes the recursive directories "upside down" one per one.

#!/bin/bash

err() { echo "$@" >&2; return 1; }

#recdir="confdir-14B---"
case $# in
1) recpath="$1" ;;
*) err "Usage: $0 /path/to/recursive_directory_name e.g. $0 ~/.Trash/somedir/confdir-14B--- " || exit 1 ;;
esac

[[ -d "$recpath" ]] || err "Directory $recpath doesn't exists." || exit 1
parent=$(dirname "$recpath")
cd "$parent" || err "Can't cd to $parent." || exit 1
recdir=$(basename "$recpath")

[[ -d "$recdir" ]] || err "Can't find $recdir in $parent" || exit 1
[[ -d "$recdir/$recdir" ]] || err "Directory $recdir in the $parent isn't recursive. The $recpath/$recdir doesn't exists." || exit 1

tmp="mvrm.$$"
[[ ! -d "$tmp" ]] || err "The $tmp exists. Can't continue" || exit 1
mv "$recdir" "$tmp"

n=0
while :
do
    [[ -d "$tmp/$recdir" ]] || break
    mv "$tmp/$recdir" .
    rmdir "$tmp"
    mv "$recdir" "$tmp"
    let n++
    echo "level $n done"
done

echo "level $(($n+1)) done"
rmdir "$tmp"
echo all done

Save it to somewhere (myself using the name deeprm.sh) and run it as:

bash script_name /path/to/recursive_dir_name

e.g.

bash ~/deeprm.sh ~/.Trash/rcs-5.9.4/confdir-14B---

Warning: The script is dangerous! Don't use it if you don't understand fully how it works.