[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Regression: "find dir/. -type d -empty -delete" claims 'unsuccessful
Dmitry V. Levin
Re: Regression: "find dir/. -type d -empty -delete" claims 'unsuccessful', breaking scripts.
Thu, 21 Nov 2013 05:56:01 +0400
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?
> >$ mkdir dir && strace -eunlinkat -- find dir/. -type d -empty -delete
> >unlinkat(AT_FDCWD, "dir/.", AT_REMOVEDIR) = -1 EINVAL (Invalid argument)
> >find: cannot delete 'dir/.': Invalid argument
> >+++ exited with 1 +++
> By "works", I mean it deletes everything from "." and below it,
$ mkdir dir dir/subdir && strace -eunlinkat -- find dir/. -type d -empty -delete
unlinkat(5, "subdir", AT_REMOVEDIR) = 0
unlinkat(AT_FDCWD, "dir/.", AT_REMOVEDIR) = -1 EINVAL (Invalid argument)
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. In this case, linux kernel denies an attempt
to unlink "dir/.", find reports the error and exits with a non-zero status.
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.
If find would do this, it would violate the principle of least surprise,
let alone posix conformance.
> >This behaviour seems to be consistent with rmdir...
> Does rmdir have a recursive behavior? If not, I wouldnt'
> say it is an equivalent argument.
Both commands honestly try to perform the action requested, but underlying
kernel denies it, so they consistently report the error and exit with a
> Compare to "cp -al dir1/. dir2/."
> Obviously you cannot link the 2 starting directories
> (or any directory underneath it), but it doesn't
> fail. There is a reason for treating dir/. differently
> from "dir/", where the latter ends with a special char to
> indicate a directory, but the former case indicates a
> "pseudo entry" and is a syntactic place holder and it's
> actual existence is implementation dependent.
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/./". Of course, "dir2/./." already exists so it doesn't need
to be created, but all "dir1/." attributes are copied to "dir2/./.".
Description: PGP signature