bug-findutils
[Top][All Lists]
Advanced

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

Re: Regression: "find dir/. -type d -empty -delete" claims 'unsuccessful


From: Linda Walsh
Subject: Re: Regression: "find dir/. -type d -empty -delete" claims 'unsuccessful', breaking scripts.
Date: Sat, 23 Nov 2013 04:39:05 -0800
User-agent: Thunderbird

On 20/11/2013 17:56, Dmitry V. Levin wrote:
On Wed, Nov 20, 2013 at 04:47:38PM -0800, Linda Walsh wrote:
On 18/11/2013 16:29, Dmitry V. Levin wrote:
On Mon, Nov 18, 2013 at 03:55:52PM -0800, Linda A. Walsh wrote:
In coreutils 8.21-7.1.3.

It has been standard to use "." in a directory to mean it's contents
on a recursive or copy  (compare cp -al src/. dst/.).

However, "find dir/. -type d -empty -delete"  works, but
Does it?
----
        Definition: The ".." and "." entries are structurally required
entries that appear to exist inside of a directory (whether or not they
actually/physically exist is implementation dependent).

        However, A directory must have those entries listed (whether they
exist or not).  "." is used a syntactic place holder to mean start from
here -- affect things below this point, but not above it.  However,
operating on "." (or deleting ".") is more like trying to delete one of
the vertices of a triangle and while still calling it a triangle.  It's
is part of the definition.

        Therefore, we've established, you can't delete "." (or "..") and
still have a valid directory entry.  Any attempt to delete either of
those entries would VOID the directory -- can cannot be allowed to actually
be performed.

        However.  For purposes of recursion.  . is a useful notation to mean
start here and work down.  POSIX uses it in its find examples.


        By "works", I mean it deletes everything from "." and below it,


find: cannot delete 'dir/.': Invalid argument
+++ exited with 1 +++

In other words, find honestly tries to unlink all empty directories in the
specified tree as requested.
---
"." isn't a directory.  It refers to the parent directory, but by itself it
is not a directory.  It has no name, and it doesn't have a separate inode
from the named directory it is in.


 In this case, linux kernel denies an attempt
to unlink "dir/.", find reports the error and exits with a non-zero status.
----
        Because you can't delete the structural entries.  Therefore programs
are *free* to use that notation to describe the contents of that directory.

        Note -- if you wanted to delete the directory you are in -- linux has
no problem doing so.  if you are in /tmp/dtmp, deleting /tmp/dtmp/. won't work
because it's not a directory.  But you CAN delete /tmp/dtmp -- and it will go
away.   If "." was really equivalent to the directory, why would /tmp/dtmp be
allowed, while /tmp/dtmp/. not be allowed?



Looks like you argue that find, instead of passing the user specified file
name to the kernel verbatim (like it does) should perform some artificial
manipulations with the user specified file name.
----
The utility always HAS been smart enough not to pass an invalid directory
name to the kernel.  It was only in find-utils 4.3 that this was added.



If find would do this, it would violate the principle of least surprise,
let alone posix conformance.
----
        Not at all.  No where does it say you have to try to remove invalid
directories.


Both commands honestly try to perform the action requested, but underlying
kernel denies it, so they consistently report the error and exit with a
non-zero status.
---
        Because "." is not a real directory.  It's a structural entry used
as a place holder.



Compare to "cp -al dir1/. dir2/."

At least in this example, cp doesn't treat "dir1/." or "dir2/."
in a special way: it really creates a hardlinked copy of "dir1/."
in "dir2/./".
----
No, it does not.  If you copy dir1/. into dir2/., it copies the contents
of dir1, but not "dir1" itself.  This is different than if you copy dir dir2/.
where it will put a copy of dir1 inside dir2.

But using cp dir1/. dir2/. only moves the *contents* of dir1 into 2.  That's
the difference.  "." represents the contents -- while the name represents
the whole directory.

Find is behaving inconstantly with historical behavior as well as commands
like "cp" and "rsync".





reply via email to

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