RFC: "-exit" option for find(1)
Peter Pentchev
roam at ringlet.net
Fri Jul 16 08:24:23 PDT 2004
On Fri, Jul 16, 2004 at 05:28:57PM +0300, Peter Pentchev wrote:
> On Fri, Jul 16, 2004 at 11:58:07AM +0400, Denis Antrushin wrote:
> > Alfred Perlstein wrote:
> > >I'm up too late, this doesn't work because find returns
> > >success whenever it successfully runs thought everything.
> > >
> > >Perhaps the primary change to just "-exit" which would
> > >make find exit successfully, and if the primary is never
> > >encountered (ie. our find logic never hits it) find would
> > >exit with a non-zero exit status?
> > >
> > >Ideas? Better ideas?
> > >
> > >The reason I want this is to avoid extracting a tarball
> > >over a directory that has files in it that are newer than
> > >the tarball.
> > >
> > >Neither tar nor find seem to make this easy...
> > What about this:
> >
> > test -n "`find . -type f -newer ../src.tar.gz`" && echo hi
>
> I believe Alfred's problem with this is that it will still traverse the
> whole hierarchy even after a match is found. In some cases, the
> hierarchy may be huge, and if the match is within the first 100-200
> files, well... :)
>
> I wonder if it wouldn't be a bit better to add to find(1) something like
> -maxmatches N, similar to Alfred's idea, but not limited to a single
> match?
Well, I've just gone ahead and implemented it: say hello to the new
-maxmatch N and -minmatch N primaries:
-maxmatch n
Always true; exits after printing out n matching filenames. If
any -maxmatch primary is specified, it applies to the entire
expression even if it would not normally be evaluated. -maxmatch
0 makes find exit immediately without performing any filesystem
traversal.
-minmatch n
Always true; exits with a non-zero exit code if less than n
matching filenames were printed out at the end of the search. If
any -minmatch primary is specified, it applies to the entire
expression even if it would not normally be evaluated.
Thus, -maxmatch 1 would help in Alfred's case. Patch attached.
G'luck,
Peter
--
Peter Pentchev roam at ringlet.net roam at sbnd.net roam at FreeBSD.org
PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553
I had to translate this sentence into English because I could not read the original Sanskrit.
-------------- next part --------------
Index: src/usr.bin/find/extern.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/extern.h,v
retrieving revision 1.21
diff -u -r1.21 extern.h
--- src/usr.bin/find/extern.h 28 May 2004 17:17:15 -0000 1.21
+++ src/usr.bin/find/extern.h 16 Jul 2004 15:09:49 -0000
@@ -68,6 +68,7 @@
creat_f c_links;
creat_f c_ls;
creat_f c_mXXdepth;
+creat_f c_mXXmatch;
creat_f c_name;
creat_f c_newer;
creat_f c_nogroup;
@@ -116,6 +117,7 @@
extern int ftsoptions, isdeprecated, isdepth, isoutput, issort, isxargs;
extern int mindepth, maxdepth;
+extern int minmatch, maxmatch, match;
extern int regexp_flags;
extern time_t now;
extern int dotfd;
Index: src/usr.bin/find/find.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/find.1,v
retrieving revision 1.66
diff -u -r1.66 find.1
--- src/usr.bin/find/find.1 7 Jul 2004 19:57:15 -0000 1.66
+++ src/usr.bin/find/find.1 16 Jul 2004 15:19:36 -0000
@@ -442,6 +442,18 @@
not normally be evaluated.
.Ic -maxdepth Li 0
limits the whole search to the command line arguments.
+.It Ic -maxmatch Ar n
+Always true; exits after printing out
+.Ar n
+matching filenames.
+If any
+.Ic -maxmatch
+primary is specified, it applies to the entire expression even if it would
+not normally be evaluated.
+.Ic Ic -maxmatch Li 0
+makes
+.Nm
+exit immediately without performing any filesystem traversal.
.It Ic -mindepth Ar n
Always true; do not apply any tests or actions at levels less than
.Ar n .
@@ -451,6 +463,14 @@
not normally be evaluated.
.Ic -mindepth Li 1
processes all but the command line arguments.
+.It Ic -minmatch Ar n
+Always true; exits with a non-zero exit code if less than
+.Ar n
+matching filenames were printed out at the end of the search.
+If any
+.Ic -minmatch
+primary is specified, it applies to the entire expression even if it would
+not normally be evaluated.
.It Ic -mmin Ar n
True if the difference between the file last modification time and the time
.Nm
Index: src/usr.bin/find/find.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/find.c,v
retrieving revision 1.17
diff -u -r1.17 find.c
--- src/usr.bin/find/find.c 28 May 2004 17:17:15 -0000 1.17
+++ src/usr.bin/find/find.c 16 Jul 2004 15:16:10 -0000
@@ -181,6 +181,10 @@
PLAN *p;
int rval;
+ if (maxmatch == 0)
+ return (0);
+
+ match = 0;
tree = fts_open(paths, ftsoptions, (issort ? find_compare : NULL));
if (tree == NULL)
err(1, "ftsopen");
@@ -237,5 +241,11 @@
(p->execute)(p, NULL);
if (errno)
err(1, "fts_read");
+
+ if (match < minmatch) {
+ warnx("Only %d of requested %d matches found",
+ match, minmatch);
+ rval = 1;
+ }
return (rval);
}
Index: src/usr.bin/find/function.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/function.c,v
retrieving revision 1.50
diff -u -r1.50 function.c
--- src/usr.bin/find/function.c 28 May 2004 17:17:15 -0000 1.50
+++ src/usr.bin/find/function.c 16 Jul 2004 15:14:20 -0000
@@ -355,6 +355,36 @@
}
/*
+ * -maxmatch/-minmatch n functions --
+ *
+ * If -maxmatch is specified, the search will stop after printing
+ * out as many matching file names. If -minmatch is specified and
+ * at the end of the search there were less matching files found,
+ * find will print out a warning and exit with a non-zero exit code.
+ *
+ * Note that -maxmatch and -minmatch are handled specially in
+ * find_execute() so their f_* functions are set to f_always_true().
+ */
+PLAN *
+c_mXXmatch(OPTION *option, char ***argvp)
+{
+ char *dstr;
+ PLAN *new;
+
+ dstr = nextarg(option, argvp);
+ if (dstr[0] == '-')
+ /* all other errors handled by find_parsenum() */
+ errx(1, "%s: %s: value must be positive", option->name, dstr);
+
+ new = palloc(option);
+ if (option->flags & F_MAXDEPTH)
+ maxmatch = find_parsenum(new, option->name, dstr, NULL);
+ else
+ minmatch = find_parsenum(new, option->name, dstr, NULL);
+ return new;
+}
+
+/*
* -acl function --
*
* Show files with EXTENDED ACL attributes.
@@ -1216,6 +1246,9 @@
f_print(PLAN *plan __unused, FTSENT *entry)
{
(void)puts(entry->fts_path);
+ match++;
+ if (match == maxmatch)
+ exit(0);
return 1;
}
@@ -1238,6 +1271,9 @@
{
fputs(entry->fts_path, stdout);
fputc('\0', stdout);
+ match++;
+ if (match == maxmatch)
+ exit(0);
return 1;
}
Index: src/usr.bin/find/main.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/main.c,v
retrieving revision 1.15
diff -u -r1.15 main.c
--- src/usr.bin/find/main.c 14 Jun 2003 13:00:21 -0000 1.15
+++ src/usr.bin/find/main.c 16 Jul 2004 15:07:00 -0000
@@ -74,6 +74,8 @@
int issort; /* do hierarchies in lexicographical order */
int isxargs; /* don't permit xargs delimiting chars */
int mindepth = -1, maxdepth = -1; /* minimum and maximum depth */
+int minmatch = -1, maxmatch = -1; /* minimum and maximum number of matches */
+int match; /* current number of matches */
int regexp_flags = REG_BASIC; /* use the "basic" regexp by default*/
static void usage(void);
Index: src/usr.bin/find/option.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/option.c,v
retrieving revision 1.22
diff -u -r1.22 option.c
--- src/usr.bin/find/option.c 28 May 2004 17:17:15 -0000 1.22
+++ src/usr.bin/find/option.c 16 Jul 2004 15:01:11 -0000
@@ -94,7 +94,9 @@
{ "-links", c_links, f_links, 0 },
{ "-ls", c_ls, f_ls, 0 },
{ "-maxdepth", c_mXXdepth, f_always_true, F_MAXDEPTH },
+ { "-maxmatch", c_mXXmatch, f_always_true, F_MAXDEPTH },
{ "-mindepth", c_mXXdepth, f_always_true, 0 },
+ { "-minmatch", c_mXXmatch, f_always_true, 0 },
{ "-mmin", c_Xmin, f_Xmin, 0 },
{ "-mnewer", c_newer, f_newer, 0 },
{ "-mtime", c_Xtime, f_Xtime, 0 },
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20040716/ea49d731/attachment.bin
More information about the freebsd-hackers
mailing list