From c66e258b4530ec1003ab2507ed26d853582fc907 Mon Sep 17 00:00:00 2001 From: jay Date: Sat, 8 Sep 2007 13:48:31 +0000 Subject: [PATCH] Doc improvement; warn against -prune ... -delete (Savannah bug #20865) --- ChangeLog | 14 ++++++++++++++ NEWS | 3 +++ doc/find.texi | 55 +++++++++++++++++++++++++++++++++++++++++++++++-------- find/find.1 | 21 ++++++++++++++++----- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 975f8c0..b484266 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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. diff --git a/NEWS b/NEWS index bb7371d..5453209 100644 --- a/NEWS +++ b/NEWS @@ -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. diff --git a/doc/find.texi b/doc/find.texi index a9e827c..4917501 100644 --- a/doc/find.texi +++ b/doc/find.texi @@ -1343,7 +1343,11 @@ find . -wholename './src/emacs' -prune , -print 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 removal succeeded. If the 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 +@samp{-print}, 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 commonly done from @code{cron}: @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 @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. +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 +@samp{-mindepth} 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: + +@c inspired by Savannah bug #20865 (Bruno De Fraine) +@example +find dirname -delete -name quux +@end 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 +@code{find} 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 +@samp{-print} 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: +@example +find dirname -path dirname/foo -prune -o -delete +@end example + +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 diff --git a/find/find.1 b/find/find.1 index 197a4e6..c6846cb 100644 --- a/find/find.1 +++ b/find/find.1 @@ -233,7 +233,8 @@ from the beginning of today rather than from 24 hours ago. This 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 not check. .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 unusual characters in filenames are handled. .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 -- 2.11.4.GIT