bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rm -f and unexecutable directories


From: Bob Proulx
Subject: Re: rm -f and unexecutable directories
Date: Sat, 8 Nov 2003 17:58:36 -0700
User-agent: Mutt/1.3.28i

Ed Avis wrote:
> Bob Proulx wrote:
> 
> >>% mkdir -p fred/jim
> >>% chmod a-x fred/jim
> >>% rm -rf fred
> >>rm: cannot chdir from `fred' to `jim': Permission denied
> >
> >But by the action of your chmod you have specifically requested that
> >you do not want those files removed!
> 
> But by specifying the -f option I (thought I had) specifically
> requested that they _should_ be removed after all!

Not quite.  You just pre-answered the questions to be asked as yes.
And the question was a silly question at that.

> Compare:
> 
> % touch foo
> % chmod a-w foo  
> % rm foo
> rm: remove write-protected regular empty file `foo'?
> [C-c]
> % rm -f foo
> [removes the file without question]
> 
> The -f flag or similar 'force' option is there to overrule any
> permissions and _force_ the files to be removed.  Or so you'd think.

Not quite.  Here is what the info page says.

`-f'
`--force'
     Ignore nonexistent files and never prompt the user.  Ignore any
     previous `--interactive' (`-i') option.

It just turns off prompting.  (Quite frankly I always thought that
behavior was a little gratuitous anyway.  But it has been the
traditional behavior.  People have come to expect it.)
Here is what the standard says.

  http://www.unix-systems.org/single_unix_specification_v2/xcu/rm.html

    If file is not of type directory, the -f option is not specified,
    and either the permissions of file do not permit writing and the
    standard input is a terminal or the -i option is specified, write a
    prompt to the standard error and read a line from the standard
    input.  If the response is not affirmative, do nothing more with the
    current file and go on to any remaining files.

The -f option only applies to the prompting which would occur if the
file were not writable.  This only applies to _files_ that are not
writable.  It does not apply to directories containing files.  In
particular it does *not* say this, "If the directory containing the
file is not writable then chmod the directory containing the file
first."  Otherwise this would be the behavior.

  mkdir -p one/two
  chmod a-x one/two one
  ls -ld one
  drw-r--r--    3 bob      bob          4096 Nov  8 17:14 one
  rm -rf one/two  # possible behavior, not real behavior.
  ls -ld one
  drwxr--r--    3 bob      bob          4096 Nov  8 17:14 one

Also, there really are multiple operations happening with the
directory find'ing, chmod'ing and rm'ing.  These are not atomic
operations.  It is possible to have a race condition between the
actions of chmod'ing and the actions of rm'ing.  Having them in one
command would imply (misleadingly) that they are atomic when they
cannot be atomic.  Look at how often people report problems with 'mv'
across filesystems not being atomic and you will see that people
really are mislead by these things.

But this is a different case than your first case.  I was confused
when I first wrote that because I thought it was this case I am about
to mention instead.  But I see that you drifted from one case to the
other as well so we were both confused by this!  Here is what I was
originally thinking about.  This one has been debated previously and
can't be changed.

  mkdir -p one/two/three
  chmod -R a-w one
  rm -rf one
  rm: cannot remove directory `one/two/three': Permission denied
  rm: cannot remove directory `one/two': Permission denied
  rm: cannot remove directory `one': Directory not empty

But your test case was "cannot chdir".  I tested with the HP-UX rm
command I get get the message "cannot search" "Permission denied" with
the legacy unix command.  So the GNU rm is behaving the same as the
traditional rm in this regard.  And 'find' also can't search the
directory.  Otherwise there would not be an error from here.

  mkdir -p one/two/three
  chmod a-x one/two/three
  find one -depth -print | xargs rmdir
  find: one/two/three: Permission denied

Of course all of the directories are removed in this case in spite of
the inability to search the directory.  That is, the following works.

  mkdir one
  chmod a-x one
  rmdir one

So perhaps there is some room for change there.  Perhaps rm should
attempt rmdir on the directory even though it can't look into it.  If
it contains files then of course it will fail to actually remove it.
But if it is empty then it would remove it.  This would be different
behavior than has existed in the rm command that everyone has been
using for the past 30 years so I would prefer not to change it.  What
does everyone else think?

> Yes - you could get the same effect by first doing 'chmod -R' and then
> 'rm -rf', but by the same argument the -f flag to cp is redundant
> because it just emulates rm followed by cp.

Actually, no, not for the non-writable file case.  It just turns off
the question.  The question originally being debated was that rm never
does a chmod and the suggestion that it should do a chmod was being
rejected because rm should not be doing a chmod.  That would certainly
make things just way too complex.

But back to your -f option on cp and rm.  The -f option never does a
chmod.  It just supresses the question for the extra code that checks
if the file is writable or not.  Using perl illustrates this since
perl does not have the extra question code in it.

> % touch foo
> % chmod a-w foo
> % rm foo
> rm: remove write-protected regular empty file `foo'?
> % rm -f foo
> [removes the file without question]

You can use perl to do the remove and it will never ask the question.
It just does the rm and does not do a chmod either.  It is not needed.

  touch foo
  chmod a-w foo
  perl -e 'unlink("foo");'
  [removes the file without question]

As you can see there is no chmod required in that case.  The -f option
does not perform any 'chmod' operations.  It just suppresses the
artificially created message.  I say artificially created because the
rm command as part of trying to be helpful goes out of its way to ask
the user if they really want to remove the file solely based upon the
clue that it is not writable.  I have always thought that behavior
gratuitous.  It is trying to create a different model of the
filesystem than the one that actually exists.  Because it tries to
overlay a different model on top of the real model it confuses people.
Perhaps the permission model of AFS is really a better way to go.  It
does seem to be more of a fit to what people actually want.

> I feel it makes sense to have forcing options built into the rm and
> cp commands themselves; of course you don't get that behaviour
> unless you explicitly ask for it.

> FWIW - what prompted me to suggest this feature was not that I had
> chmodded files to deliberately stop them being removed.  It was just a
> slightly odd tarball (not generated on a Unix system, I expect) which
> created a directory lacking execute permission.  Then I tried to use
> rm to clean up, and was surprised that even with the --force option it
> wasn't able to do the job.

At least that is not something that happens every day!  :-)

Bob




reply via email to

[Prev in Thread] Current Thread [Next in Thread]