Assaf Gordon wrote:
Hello,
Before deciding on the wording, it's worth nothing that the errors and
reasons for the errors are different between mkdir and rmdir, and
between the two cases.
On 10/18/2016 03:49 PM, L. A. Walsh wrote:
mkdir -p ./a/b/c # no error
rmdir -p ./a/b/c # get error msg, but a,b,c removed.
The error in this case (at least on Linux) is "Invalid Argument",
because 'rmdir .' is invalid and rejected by the kernel (EINVAL)
while 'mkdir .' returns EEXISTS - and '-p' specifically instruct it to
silently ignore EEXIST.
----
I see... so in ".a/b/c", a,b,c are removed, but the error
comes in "."?
$ strace -e rmdir rmdir .
rmdir(".") = -1 EINVAL (Invalid argument)
rmdir: failed to remove '.': Invalid argument
This is also mandated by posix:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html
"If the path argument refers to a path whose final component is
either dot or dot-dot, rmdir() shall fail."
---
Ok, but is "-p" a posix switch in mkdir or rmdir?
If not, wouldn't the behavior be undefined?
mkdir -p a/../b # no error
rmdir -p a/../b # error, but a & b removed
At least on my system (Linux kernel 3.13), 'a' is not removed in the
above example,
and the error is due to non-empty directory:
---
Right..., my bad, only checked 'b'. (*duh*)
Note that coreutils' mkdir contains an optimization not to try and make
'..' as it is
guaranteed to exist (implemented in gnulib's mkancesdirs.c).
---
Right, same when rmdir traverses, when it hits "..", that
must exist (even in '/').
However, by definition, when 'rmdir' traverses the directories on the
given path,
the directory 'a/..' is not empty (it contains 'a') - so this must fail.
----
with "-p"? Am talking about the case where you
create a dir with "mkdir -p "$dirname"
and later, rmdir -p "$dirname" (where dirname is passed as a parameter, but
is not user-input).
If you want to 'rmdir' to silently ignore non-empty directories,
there's a gnu extension option of 'rmdir --ignore-fail-on-non-empty':
$ strace -e rmdir rmdir --ignore-fail-on-non-empty -p a/../b
rmdir("a/../b") = 0
rmdir("a/..") = -1 ENOTEMPTY (Directory
not empty)
+++ exited with 0 +++
But note that this causes 'rmdir' to stop upon first failure, and 'a' is
still not removed.
======> seems to be best wording & solution:
"mkdir -p", it seems should really be restated to:
follow given path and make directories as possible"
then "rmdir -p" could be
"follow given path and delete directories if empty"
This does not accurately reflect how 'rmdir' is currently implemented.
A more accurate description is "follow given path and delete
directories, until the first encountered failure".
----
Right, but am trying to get rmdir to be a useful
"opposite" to a "mkdir" -- at least w/r/t "-p"...
If you want a behavior where 'rmdir' will continue beyond the first failure
and try to delete all directories in the given path (e.g. a/b/c in the
example above),
then it sounds like a new feature request, and a non-standard behavior
which will be a gnu extension (and also quite confusing behavior, IMHO).
---
Yeah -- new feature, but confusing?
I think the fact that you can mkdir -p XXX and later canNOT
rmdir -p XXX, is quite confusing behavior...
But is -p's behavior in mkdir and rmdir mandated by POSIX?