Subject: Re: bug#21084: rm appears to no longer be POSIX compliant (as of 2013 edition) re: deleting empty dirs and files under <path>/.

From: Linda Walsh <[email-masked]>
Date: Sun, 02 Aug 2015 01:02:05 -0700

Bernhard Voelker wrote:
> On 08/01/2015 05:13 AM, Linda Walsh wrote:
>> [...] for me, just the special option to allow "." or dir/. is far more
>> important.
> 
> You're discussing several aspects at once - '.' as operand, stopping
> the removal at file system boundaries, etc. - but this all sounds to me
> as if you simply wanted this one, right?
> 
>   $ find '.' -mindepth 1 -xdev -delete
---
(1) Tsk, tsk.... how could I possibly want that one when there
is no '-delete' arg in the POSIX version of find.  What were
you thinking?!   ;)

(2) You aren't really showing my example but more of
my "rmx -r ." case rmx being an alias to add -1-filesys
and using 'x' to be compatible with most other tools have
come across with such an option -- AND, my 'rmx -r .' only
takes 1/4th the space -- I design shortcuts to typing because
I can only type about 1/2 = 1/3 the speed I did before I got
a moderately nasty case of RSI -- and a boss who pushed me 
to type more in hopes that I'd quit, as he didn't have 
any thing substantial to get rid of me -- even when he wrote
a negative review -- the HR person who knew the facts told him
he had to rewrite it -- he never did.

BTW, you can make your example 2 characters shorter by removing those 
single quotes: they aren't needed.  But still 4x the typing  
for something I used alot.  But that -- also is part of the 
problem.  I have alot of scripts -- many use the standard
rm semantics and don't expect a crippled version.  Just finding
all the places it was used would be a royal pain.

(3) You aren't handling legacy SVr4 systems. The voiding of the 
standard functionality (strictly, depth-first operation: you
don't examine anything about about the current object until all of
it's children are gone -- this is especially true of the command
line arguments.

(4) The posix change made cmdline behavior inconsistent.  This
change says to process `some' newly created "restriction rules"
(for their 3 restricted paths) **before** processing contents.  However with the 1-fs 
(--one-file-system) switch, the current 'rm' does not inspect the initial
paths to verify that they are on the same filesystem -- it is only
acting on those arguments on the basis of their type: if file: delete;
if directory: descend. but it does not pay attention to their names
even long enough to do a 'stat' to check that they are really all
on 1 filesystem.  

It looks bad for rm to suddenly not fit in with other core utils
which can process "." as a __Semantic__ place-holder.  For an example
of that, we have too look into the 'arcane' 'cp' program. :)

  > if you do this:
  > cp -a dir dir1   #expected behavior: want to update maybe
  > diff -r dir dir1
  > cp -au dir dir1
  > diff -r dir dir1
  Only in dir1: dir

You can do the same example adding a slash at the end to 
force both paths to be considered dirs, but that does the
same thing..

if you try wildcards:

  > cp -aux dir/* dir1

It might work -- might not for the same reason that the
-1fs switch in rm doesn't really work as expected.  
***NOTE***: I haven't tested that example, but if does the
"right thing" then the behaviors would be different between
it and rm.

The safe way to do the update: (Note 'cp' also
has -x as did find 

  > cp -aux dir/. dir1/.
  > touch dir/newfile
  > cp -vaux dir/. dir1/. 
  ‘dir/./newfile’ -> ‘dir1/././newfile’
  > diff -r dir dir1

  >> Only the dot worked. <<

In experimenting with a few utils, I found some similar
and some different behaviors.

   > du -hdx 1 -x dir
   > du -hdx1 -x dir/.   ## both the same output.

rsync also has a -x for staying on 1 fs and has semantics not too
far off copy, but also allows "/. " semantics (been in unix since 
the earliest rm versions I saw in mid 80's.  

I seems obvious that someone got the votes to push through a
bad feature: one that was default on, and allowed for no
alternatives.  That should not be the way Gnu should handle
their SW -- a posix-compat mode, yes, but if Chet took ever non
posix feature and behavior out of bash -- it would set the shell
back 20 years.  But that's only pointing out the prevalence of
using "." as meaning "start here" across many other tools.

(5) -- the example you gave above doesn't handle a very important
case:

It doesn't handle "-f" -- first I do a find to show that I own all
the files below ".". (! -user law).

   > find . -mindepth 1 -xdev ! -user law|wc -l  #do I own all the files?
   0

Now I follow your option with the change that  I only pipe
stderr through the pipe -- which looks only for the words "Permission denied" 
and that into wc -l showing 832 errors that rm -fr . handles but are not
handled by your find example.

  > find '.' -mindepth 1 -xdev -delete 2>&1 1>/dev/null|grep Permission\ denied|wc -l
  832 

AFAIK, find, by itself, has no way to remove all of the items under a
tree even if you own them all.  Whereas rm -fr . did.
--- 

I hope my writing was sufficiently clear.  I have tried to
be clear about why I think rm w/'.' should have it's own
switch (and combining it with '..' -- I can think of 
no one or any reason to enable that functionality.  Even
though I am careful, Having the protection against doing
a bad-thing in '/' but allowing the 20+ year previous 
behavior to be returned, thus the need for a separate
switch.

Cheers!
Linda