Subject: Re: bug#42440: bug with rm
From: Bob Proulx <[email-masked]>
To: ���� <[email-masked]>
Cc: [email-masked]
Date: Wed, 22 Jul 2020 00:05:34 -0600
List-Id: <debbugs-submit.debbugs.gnu.org>

tags 42440 + notabug
thanks

���� wrote:
> sometimes,rm can't delete the file.
> but when using rm -rf + file .
> the file can be deleted.

This does not sound like a bug in the rm command.  Therefore I am
tagging this as such.  If you have follow up information and this
turns out to be an actual bug then we can reopen the bug report.

Unfortunately there is not enough information in the report to know
exactly the case that you are talking about.  For example I don't know
if you are talking about a literal "+" in that line or not.  I will
assume that you are since it is there.

There are several FAQs listed for rm.  Any of these might be a
problem.

  https://www.gnu.org/software/coreutils/faq/coreutils-faq.html#How-do-I-remove-files-that-start-with-a-dash_003f
  https://www.gnu.org/software/coreutils/faq/coreutils-faq.html#Why-doesn_0027t-rm-_002dr-_002a_002epattern-recurse-like-it-should_003f

You might have experienced either of those problems.  Or a different
problem.  We can't tell.

> sometimes,rm can't delete the file.

There are two main cases.  One is that if the file is not writable by
the user then 'rm' will check for this and ask the user for
confirmation.

    rwp@angst:/tmp/junk$ touch file1
    rwp@angst:/tmp/junk$ chmod a-w file1
    rwp@angst:/tmp/junk$ rm file1
    rm: remove write-protected regular empty file 'file1'? n
    rwp@angst:/tmp/junk$ ls -l file1
    -r--r--r-- 1 bob bob 0 Jul 21 23:52 file1

The -f option will force it without prompting.

    rwp@angst:/tmp/junk$ rm -f file1
    rwp@angst:/tmp/junk$ ls -l file1
    ls: cannot access 'file1': No such file or directory

This is a courtesy confirmation.  Because the permissions on the file
is not important when it comes to removing a directory entry.  A file
is really just an entry in the directory containing it.  Removing a
file simply removes the entry from the directory.  When the last link
to the file reaches zero then the file system reclaims the storage.
The file system is a "garbage collection" system using reference
counting.

    https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)

Therefore the only permission needed to remove a file is write
permission to the directory containing it.

    rwp@angst:/tmp/junk$ touch file2
    rwp@angst:/tmp/junk$ ls -ld . file2
    drwxrwxr-x 3 rwp rwp 100 Jul 21 23:56 ./
    -rw-rw-r-- 1 rwp rwp   0 Jul 21 23:56 file2
    rwp@angst:/tmp/junk$ chmod a-w .
    rwp@angst:/tmp/junk$ ls -ld . file2
    dr-xr-xr-x 3 rwp rwp 100 Jul 21 23:56 ./
    -rw-rw-r-- 1 rwp rwp   0 Jul 21 23:56 file2

This creates a file.  The file is writable.  But I have changed the
directory containing it not to be writable.  This prevents the ability
to remove the file.  Can't remove it because the directory is not wriable.

    rwp@angst:/tmp/junk$ rm file2
    rm: cannot remove 'file2': Permission denied
    rwp@angst:/tmp/junk$ rm -f file2
    rm: cannot remove 'file2': Permission denied
    rwp@angst:/tmp/junk$ rm -rf file2
    rm: cannot remove 'file2': Permission denied
    rwp@angst:/tmp/junk$ ls -ld . file2
    dr-xr-xr-x 3 rwp rwp 100 Jul 21 23:56 ./
    -rw-rw-r-- 1 rwp rwp   0 Jul 21 23:56 file2

In order to remove the file we must have write permission to the
directory.  Adding write permission to the directory allows removing
the file.

    rwp@angst:/tmp/junk$ chmod ug+w .
    rwp@angst:/tmp/junk$ rm file2
    rwp@angst:/tmp/junk$ ls -ld file2
    ls: cannot access 'file2': No such file or directory

Expanding upon this problem is if there are many directories deep and
the directories are not writable.

    rwp@angst:/tmp/junk$ mkdir -p dir1 dir1/dir2 dir1/dir2/dir3
    rwp@angst:/tmp/junk$ touch dir1/dir2/dir3/file3
    rwp@angst:/tmp/junk$ chmod -R a-w dir1
    rwp@angst:/tmp/junk$ find dir1 -ls
     69649132      0 dr-xr-xr-x   3 rwp      rwp            60 Jul 22 00:00 dir1
     69649133      0 dr-xr-xr-x   3 rwp      rwp            60 Jul 22 00:00 dir1/dir2
     69649134      0 dr-xr-xr-x   2 rwp      rwp            60 Jul 22 00:00 dir1/dir2/dir3
     69650655      0 -r--r--r--   1 rwp      rwp             0 Jul 22 00:00 dir1/dir2/dir3/file3

That sets up the test case.  None of the directories are wriable.
Therefore we cannot remove any of them.  The directory holding the
entries must be writable.

    rwp@angst:/tmp/junk$ rm -rf dir1
    rm: cannot remove 'dir1/dir2/dir3/file3': Permission denied

Even using 'rm -rf' does not work.  And should not work.  Because the
directories are not writable.

In order to remove these files the directories must be made writable.

    rwp@angst:/tmp/junk$ chmod -R u+w dir1
    rwp@angst:/tmp/junk$ rm -rf dir1
    rwp@angst:/tmp/junk$ ls -ld dir1
    ls: cannot access 'dir1': No such file or directory

Hopefully this helps you understand how directory entries work, that
the directory holding an entry (either file or another directory) must
be writable.  How to add write permission.  How to remove a single
file.  How to remove a directory tree.  Hopefully this helps! :-)

Bob