Subject: bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call

From: Linda Walsh <[email-masked]>
Date: Tue, 19 Nov 2013 16:02:48 -0800

On 19/11/2013 12:45, Bob Proulx wrote:
> 
>> Since when do you think of a "call" as being a command?
> 
> We don't.  But from what you wrote ("Does the posix "remove" call
> require a -d?") makes it appear that you think the posix remove(3)
> library call is a command.  Because library calls do not take options
> like that while commands do.
----
	Well, that was a bit of metaphore, insomuch as the POSIX
calls talk about flag passing with a value of AT_REMOVEDIR to do something
different...   -d in a call would likely be passed as an option

> 
>>> Sorry, but to change that, you'd have to go back in time 30 or 40 years
>>> to when rm(1) was first written.  People have grown to rely on 'rm(1)'
>>> being a wrapper around unlink(2), 'rmdir(1)' being a wrapper around
>>> rumdir(2), and 'rm(1) -R' being a wrapper around rmdir(2) or unlink(2)
>>> as needed.
> 
> Agreed.  Let's not break this.
----

I'm not see what would break.  instead of failing to remove a non-empty
directory, it would remove it (if it was empty and permissions allowed).

> 
>>    People relied on rm removing files in a depth first search order
>> for 30-40 years.
> 
> When using 'rm -rf' they do.  But only with the -r option.  Never
> without it.
---
Absolutely... that's what I was referring to, sorry for unclarity.

> 
> The change you have proposed would for the first time in all of those
> years have rm remove a directory without the -r option.  That would be
> bad because it would introduce bugs into scripts that are expecting
> the existing behavior of rm not removing directories.  (Unless the -r
> option is given.)
----
I would ask how it would fail in a script -- I.e. we are only talking
empty directories -- and currently an error would be returned if
a script tried to do that.  If the script was catching errors or running
with "-e", the script would terminate under the current implementation.

So no script could ever "work" relying on itself to be fail -- it's a
contradiction in terms.

> 
>> Posix changed that requiring special checks for ".".  Scripts relied
>> on that behavior for 30-40 years as well...  If you want to use that
>> reasoning, rm should go back to doing depth first deletion and
>> reporting an error with deleting "." when it is finished.
> 
> I actually agree with you on that point. ;-)
> (Regarding 'rm -rf .')
----

	Well, that's what much of my interest in this area
and the newly created bug in "find" hinges on.

> 
>>> Sorry, but doing things in rm(1) in a different order than POSIX
>>> describes would lead to subtle breakage to lots of existing scripts.
>> ----
>>    I claim not.  Come up with 1 case where scripts rely on the current
>> behavior -- to "die" before doing anything useful, vs. the pre-existing
>> behavior which was to issue an error (suppressible with "-f") on the
>> final deletion failing.
> 
> I have seen many various script writing styles.  Some of them are
> atrocious indeed.  I would expect to at some point see someone use rm
> on file system objects with abandon thinking that they won't remove
> directories.  Suddenly they will be able to remove directories.  That
> would be a change in behavior.  Changing established behavior is bad.
-----
	*empty directories*.. lets be clear.  I am NOT proposing that
"rm" recursively remove anything without "-r"...

> 
> I routinely use the opposite side of things myself.  I routinely use
> rmdir on empty directories knowing that if the directory is not empty
> that it will fail and not remove any actual file content.  I could
> definitely see someone counting on the behavior that rm removes files
> but never removes directories.  (Unless the -r option is given.)
----
	I use the fact that rm doesn't remove non-empty directories
as well.. I'm not questioning that behavior.

	If someone relied on using "rm" to clean out a directory
of any "fluff" or "dander" that had built up... I strongly believe
that if "rm" also removed *empty* directories,  it would be more likely
to be appreciated by soemone who was using it to get rid of all the
spurious file entries -- as empty directory entries are often just as
spurious -- I'm often cleaning out skeletal trees of directories on my
systems... I've even thought about the usefulness of "rmdir -r" --
which would recursively remove empty dirs starting at the top (with
a limitation for "-xdev"... (I know about rmdir -p a/b/c).. but empty, wider
skeletons are more common than skinny+tall dir-structures. (skinny=1 dir wide,
many dirs deep).

> 
>>    I am calling your bluff -- show me the scripts (other than a posix
>> conformance test script), that would fail -- subtly or otherwise.
> 
> Anything I show would be contrived.  But that doesn't mean that
> changing the behavior should be done.
> 
>   mkdir a b c
>   touch aa bb cc
>   for f in *; do rm "$f"; done
> 
> With existing behavior the directories would remain.  With the new
> proposed behavior the directories would be removed.  That is a
> behavior change that should not be made.
----
	Why not?  if you want 1 command that does both, why not
implement a remove command == but wouldn't it commonly be
abbreviated as 'rm'...?

	It would be a change.  But it's not something that
would cause the level of problems associated with disabling "rm -fr ." --
and that crippling change was made w/o a blink of an eyelash.

	(then Erik gets a bug up his **, about thinking
how "useful" it is to have "find . -type d -empty -delete" always
exist with a failure code.  Just lovely.)  ;-/

> 
> If you want that behavior then the -d option is present and
> available.  Simply use the -d option.
> 
>   mkdir a b c
>   touch aa bb cc
>   for f in *; do rm -d "$f"; done
---
	I could alias that, I s'pose.. and see
if any scripts fail because of it... ;-)

> 
> That gives you the behavior you are requesting.
> 
>>    I assert they don't exist for 2 reasons.  The foremost being
>> that working scripts cannot rely on upon the deletion failure
>> stopping any useful work being done by the command.
> 
> See the above example.
-----
	a demo script isn't a working script, nor is it a
script that does any useful work.  I specifically excluded
posix compliance scripts -- which the above would be be more
likely to be than a "working script"...

>> The 2nd being it was a new change in posix that appeared in gnu
>> utils in only the past few years.  The previous 25-35 years of
>> scripts would have relied on it working as *documented* (depth
>> first).
> 
> Since you are mentioning depth first I can only think you are talking
> about 'rm -r'.  How does that tie into remove(3)?
----
	Only insomuch as empty dir removal is less of a feature change
than aborting the entire command.

>
>> By your own standards for not changing something, "rm" should
>> be fixed to be the way it was for 30-40 years, as.
> 
> Huh?  Stop here.  Please explain.  Your words here do not follow.
---
	Eric said that because rm was the way it was (failing on
dir deletes) for 30-40 years, was reasoning not to change it, when
the only consequence was ability to delete empty dirs, then
undoing the posix damage of removing the entire functionality of
being able to have rm create a pristine dir w/1 command  (as well
as not crossing fs-boundaries).  Even using "rm *" in the directory
if something in dir is a mount.. you end up deleting things on other
file systems (I got the T-shirt; ;~>).

> 
>> The problem is, is that by implementing that change, functionality
>> was lost and removed in "rm".   The earlier version had more
>> functionality.  So you can't come up with scripts that rely on
>> missing functionality to get things done.  It's like relying on
>> missing water to water your plants or missing food to feed yourself.
> 
> Are you talking about 'rm -rf .'?  I agree with you on that one.  That
> was a bad change to disallow it.  It just wasn't as severe as what you
> are proposing.  Disallowing 'rm -rf .' is a nanny-state type of
> behavior.  It annoys me.  It shouldn't have been done.  But changing
> unlink(2) to remove(3) is much more severe and really, really
> shouldn't be done.
----
	I see the consequences of "rm -fr ." being worse, as the
work-arounds have more mine-fields -- like deleting things
on other file systems.  As opposed to the unlink->remove change
which would delete *empty directories*... I don't see that
as nearly as harmful as deleting entire file-systems on
mounted dirs...

But to throw salt in the wound, Erik changed find so that
it complains if you try to delete "." as in
"find . -type d -empty -delete" -- my snapshot script used
that as well as "rm -fr ." to clean out directories to
be prepared to do "diffs" into.  The find-clean empty dirs
command is more of a way to save about 1-2% on space, as
rsync likes to copy dirs over if the times are different
(even when it is told not to copy empty dirs)...

Anyway, that was the latest bug-up-my bonnet that caused
me to think about these issues again.. trying to come
up with anything useful.. like rm removing empty
dirs seemed like it would be a minimal damage thing compared
to other damage.

As for rm-fr. = nanny ... yes.. got the impression
it was implemented on BSD systems to protect the
college kids -- but that wouldn't prevent allowing
it with an ENV flag that lists commands to exclude
from nanniness... some
ENV flag EXPERT_MODE="rm(.),find(delete)"
commands as needed"