bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Workaround: find . -delete Bob not the first thing one one think of to rm a dir tree. I didn't even know find had a delete op... (use find alot, but 70% of the time it's to pipe into xargs...)
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Jim Meyering wrote: Could you be thinking of some other rm? Coreutils' rm has rejected that for a long time: ... POSIX requires rm to reject any attempt to delete an explicitly specified . or .. argument (or any argument whose last component is one of those): Hmm... Wow. I decided to check HP-UX 11.11, a now rather old release from twelve years ago in 2000, the oldest easily available to me, and got this: $ /usr/bin/rm -rf . rm: cannot remove .. or . So I guess GNU coreutils is in good company with traditional Unix systems! It has definitely been that way for a long time. Bob
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is
Bob Proulx writes: Jim Meyering wrote: Could you be thinking of some other rm? Coreutils' rm has rejected that for a long time: ... POSIX requires rm to reject any attempt to delete an explicitly specified . or .. argument (or any argument whose last component is one of those): Hmm... Wow. I decided to check HP-UX 11.11, a now rather old release from twelve years ago in 2000, the oldest easily available to me, and got this: $ /usr/bin/rm -rf . rm: cannot remove .. or . So I guess GNU coreutils is in good company with traditional Unix systems! It has definitely been that way for a long time. Linux has the ability to actually remove a directory that is empty but still referenced as the cwd of some process. This ability is non-traditional (my fuzzy memory says it showed up some time in the 2.2 or 2.4 era). It's worth considering whether this change should be reflected by a relaxation of rm's traditional behavior. rm -rf $PWD, meaning basically the same thing as rm -rf ., works, and leaves you in a directory so empty that ls -a reports no . or .. entries, and no file can be created in the current directory. (open and stat and chdir still work on . and .. though. They're magic.) -- Alan Curry
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Bob Proulx wrote (Monday, September 03, 2012 9:51 AM) Jim Meyering wrote: Could you be thinking of some other rm? Coreutils' rm has rejected that for a long time: ... POSIX requires rm to reject any attempt to delete an explicitly specified . or .. argument (or any argument whose last component is one of those): Hmm... Wow. I decided to check HP-UX 11.11, a now rather old release from twelve years ago in 2000, the oldest easily available to me, and got this: $ /usr/bin/rm -rf . rm: cannot remove .. or . So I guess GNU coreutils is in good company with traditional Unix systems! It has definitely been that way for a long time. Seconded! SunOS 5.9: $ rm -rf . $ rm -r . rm of . is not allowed Have a nice day, Berny
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is
Alan Curry wrote: Bob Proulx writes: Jim Meyering wrote: Could you be thinking of some other rm? Coreutils' rm has rejected that for a long time: ... POSIX requires rm to reject any attempt to delete an explicitly specified . or .. argument (or any argument whose last component is one of those): Hmm... Wow. I decided to check HP-UX 11.11, a now rather old release from twelve years ago in 2000, the oldest easily available to me, and got this: $ /usr/bin/rm -rf . rm: cannot remove .. or . So I guess GNU coreutils is in good company with traditional Unix systems! It has definitely been that way for a long time. Linux has the ability to actually remove a directory that is empty but still referenced as the cwd of some process. This ability is non-traditional (my fuzzy memory says it showed up some time in the 2.2 or 2.4 era). It's worth considering whether this change should be reflected by a relaxation of rm's traditional behavior. I see very little benefit in relaxing this restriction. Why introduce an incompatibility (slightly dangerous, even) with POSIX and with such long-standing behavior? rm -rf $PWD, meaning basically the same thing as rm -rf ., works, and leaves If you use that, in general you would want to add quotes, in case there are spaces or other shell meta-characters: rm -rf $PWD you in a directory so empty that ls -a reports no . or .. entries, and no file can be created in the current directory. (open and stat and chdir still work on . and .. though. They're magic.)
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is
Jim Meyering writes: Alan Curry wrote: rm -rf $PWD, meaning basically the same thing as rm -rf ., works, and leaves If you use that, in general you would want to add quotes, in case there are spaces or other shell meta-characters: rm -rf $PWD Well, when I do it I'm in zsh which has fixed that particular Bourne shell design error. -- Alan Curry
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is
Alan Curry wrote: Jim Meyering writes: Alan Curry wrote: rm -rf $PWD, meaning basically the same thing as rm -rf ., works, and leaves If you use that, in general you would want to add quotes, in case there are spaces or other shell meta-characters: rm -rf $PWD Well, when I do it I'm in zsh which has fixed that particular Bourne shell design error. I use zsh on the command line, too (Go zsh! :-), but few have the luxury of being able to target zsh as their sole bourne-like shell interpreter.
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Jim Meyering wrote: I see from your mention of . below that you are objecting to rm's refusal to remove . or ... --- I see from your response that you misunderstood what I wrote. There was no mention of ... I wouldn't expect rm to crawl backward out of a rm in any even -- error message or not. POSIX requires rm to reject any attempt to delete an explicitly specified . or .. argument (or any argument whose last component is one of those): http://pubs.opengroup.org/onlinepubs/95399/utilities/rm.html --- But you fail to follow the earlier stated POSIX requirement: .. If this fails for any reason, rm shall write a diagnostic message to standard error, do nothing more with the current file, and go on to any remaining files. Specifically, in regards to a failure to remove a directory: For each entry contained in file, other than dot or dot-dot, the four steps listed here (1 to 4) shall be taken with the entry as if it were a file operand. The rm utility shall not traverse directories by following symbolic links into other parts of the hierarchy, but shall remove the links themselves. So for each entry in ., except for . and .., rm is to traverse and remove them even after encountering an error -- which normally, it would only encounter at the end of removing all files in the directory. Sides -- it normally does depth-first traversal --- since you can't delete a dir with contents still in it -- so why different for '.'? Safety, I suspect. . and .. may not mean anything to a novice. Again, .. isn't the issue anymore than it should be skipped. What is at issue is the order of deletion (depth first), and it's not continuing to delete the other entires in the 'file' other than . and .. after encountering any errors (including a rejection to delete . and ..). So the error message is fine. But not deleting everything else in the dir isn't (at least judging from the POSIX doc you pointed me at... -- Thanks for the reference!
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Linda Walsh coreut...@tlinx.org writes: But you fail to follow the earlier stated POSIX requirement: You failed to read the second paragraph: If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic message to standard error and do nothing more with such operands. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different.
bug#12334: [patches] two tiny textual fixes for 'touch'
On Sun, Sep 2, 2012, at 18:10, Jim Meyering wrote: Sure, but please s/recognized/accepted/. Then let it be, as for me accepted means just about the opposite of ignored. I chose recognized because 'touch' reacts to an option it does not know at all with: unrecognized option. $ touch --the bell touch: unrecognized option '--the' Benno -- http://www.fastmail.fm - A no graphics, no pop-ups email service
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Andreas Schwab wrote: [...] read the second paragraph: If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic message to standard error and do nothing more with such operands. Coreutils has already implemented an exception for the root directory: --no-preserve-root (whatever this would be useful for except investigating what'd happen in a VM ...). So it'd be possible to have another new switch to exceptionally permit removing ., although - again - I don't see much gain over `rm -rf $PWD` or `find . -delete`. -1 from me. Moreover, I'd remove support for --[no-]preserve-root in rm: preserving is mandatory by POSIX, and not preserving is senseless. Have a nice day, Berny
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Andreas Schwab wrote: If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic message to standard error and do nothing more with such operands. --- You are right. This only further cements the worthlessness of the 2003 revision in it's claim as being a POSIX standard. The problem is that the initial standard didn't have many of these restrictions. I don't know about this specific one, but I bet it wasn't in *THE* POSIX standard. The idea of a POSIX standard was to make things compatible and provide a set of features for portable execution. Later revisions have mostly about adding restrictions. Most recently I observed a discussion on one of the posix lists about how further screw with people by restricting filename chars from the current set [^/\000] to [^/\000-\040]: No more file names like this. This showed the braindead nature of the poster who forgot to restrict non-printing chars further up in the unicode range. - Voelker, Bernhard wrote: Andreas Schwab wrote: [...] read the second paragraph: If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic message to standard error and do nothing more with such operands. Coreutils has already implemented an exception for the root directory: --no-preserve-root (whatever this would be useful for except investigating what'd happen in a VM ...). --- And by doing so has violated posix, since it doesn't say that if a switch is present, you can override the 2nd paragraph. If we are going to be stricly posix, it says if the arg is the root directory -- the util must have nothing more to do with the operand. Adding special except if this, options doesn't make it posix compatible. It's interesting how people can rationalize that's it's ok to violate the standard for their special pet case, but when it comes to one's proposed by someone else, it's all nope, not sorry -- and we can't remove _my_ feature for backwards compat reasons. Obviously, the same workaround that was prescribed for working around . would work for /, namely: 'find / -delete'. If you are are going to rigidly adhere to a broken standard that is becoming more broken and restricted over time, you can't put in pet exceptions while using POSIX compat as a justification for not allowing other, more user friendly, options. so +1 to Bernhard for point that out, but a -1 to those who don't cite posix as an excuse, yet allow overrides that are non posix. More generally, -1 to the bad trend of taking a portable OS Exchange specification and turning it into a list of thou shalt not's... As if we need another list of those... The first has been a great excuse for oppression and mass murder... I wonder how high people elevate the holy P.O.S.ix. :-( --- Hey, I know... lets just add a new util 'r', does the job of rm and rmdir combined w/o unnecessary posix restrictions. r -f . (automatically does what is needed to remove . -- including files beneath it). Interesting fact -- MS's netsh, allows you to type the minimum number of chars of a command that are unambiguous to execute it.
bug#12334: [patches] two tiny textual fixes for 'touch'
Benno Schulenberg wrote: On Sun, Sep 2, 2012, at 18:10, Jim Meyering wrote: Sure, but please s/recognized/accepted/. Then let it be, as for me accepted means just about the opposite of ignored. I chose recognized because 'touch' reacts to an option it does not know at all with: unrecognized option. $ touch --the bell touch: unrecognized option '--the' Leaving things as-is is fine with me. I've marked this ticket as done.
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
I was about to suggest the following, on GNU/Linux: # Don't do this unless you know what you're doing! rm -fr /proc/self/cwd/ Except it doesn't work! Not even if I append '.': $ mkdir /tmp/victim $ cd /tmp/victim $ touch foo $ rm -fr /proc/self/cwd/ rm: cannot remove `/proc/self/cwd': Too many levels of symbolic links $ rm -fr /proc/self/cwd/. rm: cannot remove directory: `/proc/self/cwd/.' $ ls foo Aren't these bugs, at least?
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
On 09/03/2012 10:04 PM, Paul Eggert wrote: I was about to suggest the following, on GNU/Linux: # Don't do this unless you know what you're doing! rm -fr /proc/self/cwd/ Except it doesn't work! Not even if I append '.': $ mkdir /tmp/victim $ cd /tmp/victim $ touch foo $ rm -fr /proc/self/cwd/ rm: cannot remove `/proc/self/cwd': Too many levels of symbolic links That is in rm_fts(): /* Perform checks that can apply only for command-line arguments. */ if (ent-fts_level == FTS_ROOTLEVEL) { if (strip_trailing_slashes (ent-fts_path)) ent-fts_pathlen = strlen (ent-fts_path); ent-fts_path is stripped from /proc/self/cwd/ to /proc/self/cwd. Then this: Ternary is_empty_directory; enum RM_status s = prompt (fts, ent, true /*is_dir*/, x, PA_DESCEND_INTO_DIR, is_empty_directory); if (s == RM_OK is_empty_directory == T_YES) { /* When we know (from prompt when in interactive mode) that this is an empty directory, don't prompt twice. */ s = excise (fts, ent, x, true); fts_skip_tree (fts, ent); } s is RM_OK, but is_empty_directory is T_NO, because it's no DIR ... The FTS loop continues and diagnoses ELOOP. That's the strace output: newfstatat(AT_FDCWD, /proc/self/cwd/, {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(AT_FDCWD, /proc/self/cwd, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 ELOOP (Too many levels of symbolic links) openat(AT_FDCWD, /proc/self/cwd, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 ELOOP (Too many levels of symbolic links) unlinkat(AT_FDCWD, /proc/self/cwd, AT_REMOVEDIR) = -1 EACCES (Permission denied) The example applies to all symlinks to directories (i.e. not only to /proc/self/cwd): $ mkdir d $ touch d/file $ ln -s d dl $ rm -rv dl/ /home/berny/cu/src/rm: cannot remove ‘dl’: Too many levels of symbolic links However, in this case, unlinkat returns ENOTDIR: unlinkat(AT_FDCWD, dl, AT_REMOVEDIR) = -1 ENOTDIR (Not a directory) $ rm -fr /proc/self/cwd/. rm: cannot remove directory: `/proc/self/cwd/.' $ ls foo That's the dot case. Aren't these bugs, at least? The latter: no, because dot must not be removed. The former: maybe, but the question is what rm should remove: the symlink or the target? The info page is quiet about this. I tend to say it's okay as it is, because if someone wants to remove the target of a symlink,(s)he can always to $ rm -rv $(readlink -f dl) Only the diagnostic (ELOOP) looks a bit strange ... Have a nice day, Berny
bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
On 09/03/2012 10:20 PM, Bernhard Voelker wrote: the question is what rm should remove: the symlink or the target? The convention in POSIX is that if a symlink is followed by '/', it's dereferenced. So this does appear to be a bug in coreutils 'rm'. I confirmed that the bug does not occur with Solaris 11 'rm': $ mkdir d $ touch d/file $ ln -s d dl $ ls -al * lrwxrwxrwx 1 eggert faculty1 Sep 3 22:26 dl - d d: total 16 drwxrwxr-x 2 eggert faculty 178 Sep 3 22:26 . drwxrwxr-x 3 eggert faculty 234 Sep 3 22:26 .. -rw-rw-r-- 1 eggert faculty0 Sep 3 22:26 file $ rm -r dl/ $ ls -al * lrwxrwxrwx 1 eggert faculty1 Sep 3 22:26 dl - d Thanks for reminding me about . and explaining why the other example is not a bug.