Subject: Re: bug#18491: rm -r fails to delete entire hierarchy when path goes in and out of it

From: Gian Ntzik <[email-masked]>
Date: Fri, 19 Sep 2014 04:47:38 +0100

"Linda A. Walsh" <[email-masked]> writes:

> Bob Proulx wrote:
>> Gian Ntzik wrote:
>>> It seems that using rm -r with a path that goes into a (non-empty)
>>> directory intended for removal (and back up e.g. using dot-dots) fails
>>> to remove the directory. The directory is rendered empty, but itself not
>>> removed.
>>>
>>> For example,
>>>
>>> $ mkdir -p /tmp/a/b/c
>>> $ mkdir -p /tmp/a/e
>>> $ rm -r /tmp/a/b/../../a
>>> rm: cannot remove ‘/tmp/a/b/../../a’: No such file or directory
>>
>> Trying to do anything to work around this seems wrong to me since it
>> will require keeping track of the state before and simulating to
>> create the desired state afterward and then applying a derived state
>> change to the file system.  That is much too complex for this simple
>> operation.
> ----
>     One would think the same for rm -fr "foo/.", but the
> straight-forward application of the depth-first removal was
> removed from "rm" for special cases.  One would think
> that the underlying tree might be easily addressed:
>
> function rmr {
>   local rd=$(cd "$1"; /bin/pwd)
>   echo rm -r "$rd"
> }
>

Yes, this would work because getcwd() gives a canonical path (no dot-dot
or symlinks). Issues like the one reported do not arise with canonical paths.
Another simple way to address the issue could be:

if [ -d $1 ]
then
    rm -r "$(/bin/readlink -e $1)"
else
    rm -r "$1"
fi

which does not change the cwd.

(assume that sufficient on the argument ending in dot, dot-dot or being
/ are done beforehand).