[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Regression: "find dir/. -type d -empty -delete" claims 'unsuccessful
Re: Regression: "find dir/. -type d -empty -delete" claims 'unsuccessful', breaking scripts.
Wed, 20 Nov 2013 16:47:38 -0800
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
$ 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,
unlike "rm -fr .", which broke 30-40 years of behavior
and added an "out-of-process" check on the path that is NOT
in depth first order. Apparently this behavior only existed in
BSD where it was put in to protect the children^h^h^h er, students.
(in the US, nearly any mindless rule or law can be justified with
the phrase "to protect the children").
My beef with "find", was the addition of a pointless error
such that there is no way, now, to tell if the command really did
what you wanted it to do. You have to give it a starting point.
POSIX lists "." in most or nearly all of their examples
under "find", as a starting point for "find". To make the common
starting case always fail in a meaningless manner (i.e. ". must always
fail, so all invocations of "find" to remove all entries BELOW a
specific directory must end with an error). If you force "."
to give an error message, then you have no way to delete all files
*in* a directory (but not the directory itself).
must end with an error.
This behaviour seems to be consistent with rmdir...
Does rmdir have a recursive behavior? If not, I wouldnt'
say it is an equivalent argument.
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.
Does that make it more clear?