Index: ChangeLog =================================================================== RCS file: /sources/findutils/findutils/ChangeLog,v retrieving revision 1.267 diff -u -p -r1.267 ChangeLog --- ChangeLog 8 Sep 2007 12:44:42 -0000 1.267 +++ ChangeLog 8 Sep 2007 13:47:03 -0000 @@ -1,3 +1,17 @@ +2007-09-08 James Youngman + + * doc/find.texi (Directories): Mention that "-prune ... -delete" + will not do what you want and will cause the deletion of more + files than you probably intended. + (Delete Files): Likewise, suggest using "-depth" when testing + command lines you plan to eventually add "-delete" to. + (Cleaning Up): Add -depth explicitly to an example which uses + -delete. + * find/find.1 (-depth): Mention that -delete also implies -depth. + (-delete): Warn against putting -delete first. + (-prune): Also warn against -prune ... -delete. + NEWS: Mention these changes. + 2007-08-23 Eric Blake Pick up gnulib change to getline module. Index: NEWS =================================================================== RCS file: /sources/findutils/findutils/NEWS,v retrieving revision 1.207 diff -u -p -r1.207 NEWS --- NEWS 23 Aug 2007 09:10:15 -0000 1.207 +++ NEWS 8 Sep 2007 13:47:04 -0000 @@ -76,6 +76,9 @@ find manual page. #20529: removed spurious 'o' in description of "xargs -a" in doc/find.texi. +#20865: Better documentation on the fact that -delete implies -depth +and that -delete interacts badly with -prune. + ** Translations Updated Dutch translation. Index: doc/find.texi =================================================================== RCS file: /sources/findutils/findutils/doc/find.texi,v retrieving revision 1.146 diff -u -p -r1.146 find.texi --- doc/find.texi 22 Aug 2007 21:53:58 -0000 1.146 +++ doc/find.texi 8 Sep 2007 13:47:06 -0000 @@ -1343,7 +1343,11 @@ find . -wholename './src/emacs' -prune , If the @samp{-depth} option is in effect, the subdirectories will have already been visited in any case. Hence @samp{-prune} has no effect -and returns false. +and returns false. + +Because @samp{-delete} implies @samp{-depth}, using @samp{-prune} in +combination with @samp{-delete} may well result in the deletion of +more files than you intended. @end deffn @@ -2539,7 +2543,10 @@ Delete files or directories; true if rem removal failed, an error message is issued. The use of the @samp{-delete} action on the command line automatically -turns on the @samp{-depth} option (@pxref{find Expressions}). +turns on the @samp{-depth} option (@pxref{find Expressions}). This +can be surprising if you were previously just testing with address@hidden, so it is usually best to remember to use @samp{-depth} +explicitly. @end deffn @node Adding Tests @@ -3714,14 +3721,46 @@ Removing old files from @file{/tmp} is c @c Idea from Kaveh Ghazi. @example -find /tmp /var/tmp -not -type d -mtime +3 -delete -find /tmp /var/tmp -depth -mindepth 1 -type d -empty -delete +find /tmp /var/tmp -depth -not -type d -mtime +3 -delete +find /tmp /var/tmp -depth -mindepth 1 -type d -empty -delete address@hidden example + +The second @code{find} command above cleans out empty directories +depth-first (@samp{-delete} implies @samp{-depth} anyway), hoping that +the parents become empty and can be removed too. It uses address@hidden to avoid removing @file{/tmp} itself if it becomes +totally empty. + + +Lastly, an example of a program that almost certainly does not do what +the user intended: + address@hidden inspired by Savannah bug #20865 (Bruno De Fraine) address@hidden +find dirname -delete -name quux address@hidden example + +If the user hoped to delete only files named @file{quux} they will get +an unpleasant surprise; this command will attempt to delete everything +at or below the starting point @file{dirname}. This is because address@hidden evaluates the items on the command line as an expression. +The @code{find} program will normally execute an action if the +preceeding action succeeds. Here, there is no action or test before +the @samp{-delete} so it will always be executed. The @samp{-name +quux} test will be performed for files we successfully deleted, but +that test has no effect since @samp{-delete} also disables the default address@hidden operation. So the above example will probably delete a +lot of files the user didn't want to delete. + +This command is also likely to do something you did not intend: address@hidden +find dirname -path dirname/foo -prune -o -delete @end example -The second @code{find} command above uses @samp{-depth} so it cleans -out empty directories depth-first, hoping that the parents become -empty and can be removed too. It uses @samp{-mindepth} to avoid -removing @file{/tmp} itself if it becomes totally empty. +Because @samp{-delete} turns on @samp{-depth}, the @samp{-prune} +action has no effect and files in @file{dirname/foo} will be deleted +too. + @node Strange File Names @section Strange File Names Index: find/find.1 =================================================================== RCS file: /sources/findutils/findutils/find/find.1,v retrieving revision 1.86 diff -u -p -r1.86 find.1 --- find/find.1 22 Aug 2007 21:53:58 -0000 1.86 +++ find/find.1 8 Sep 2007 13:47:06 -0000 @@ -233,7 +233,8 @@ from the beginning of today rather than option only affects tests which appear later on the command line. .IP \-depth -Process each directory's contents before the directory itself. +Process each directory's contents before the directory itself. The +\-delete action also implies \-depth. .IP \-follow Deprecated; use the \-L option instead. Dereference symbolic links. @@ -744,7 +745,16 @@ the type of the file that \-type does no .IP "\-delete\fR" Delete files; true if removal succeeded. If the removal failed, an error message is issued. Use of this action automatically turns on -the `\-depth' option. +the `\-depth' option. Don't forget that the find command line is +evaluated as an expression, so putting \-delete first will make +.B find +try to delete everything below the starting points you specified. +When testing a +.B find +command line that you later intend to use with \-delete, you should +explicitly specify \-depth in order to avoid later surprises. Because +\-delete implies \-depth, you cannot usefully use \-prune and \-delete +together. .IP "\-exec \fIcommand\fR ;" Execute \fIcommand\fR; true if 0 status is returned. All following @@ -1104,9 +1114,10 @@ section for information about how unusua .RE .IP \-prune If \-depth is not given, true; if the file is a directory, do not descend -into it. -.br -If \-depth is given, false; no effect. +into it. If \-depth is given, false; no effect. +Because +\-delete implies \-depth, you cannot usefully use \-prune and \-delete +together. .IP "\-quit" Exit immediately. No child processes will be left running, but no more