Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Jul 2004 18:24:19 +0300
From:      Peter Pentchev <roam@ringlet.net>
To:        Denis Antrushin <DAntrushin@mail.ru>, Alfred Perlstein <alfred@freebsd.org>, hackers@freebsd.org
Subject:   Re: RFC: "-exit" option for find(1)
Message-ID:  <20040716152418.GB1589@straylight.m.ringlet.net>
In-Reply-To: <20040716142856.GA1589@straylight.m.ringlet.net>
References:  <20040716071545.GW95729@elvis.mu.org> <20040716072341.GX95729@elvis.mu.org> <40F78A8F.2010502@mail.ru> <20040716142856.GA1589@straylight.m.ringlet.net>

next in thread | previous in thread | raw e-mail | index | archive | help

--qtZFehHsKgwS5rPz
Content-Type: multipart/mixed; boundary="St7VIuEGZ6dlpu13"
Content-Disposition: inline


--St7VIuEGZ6dlpu13
Content-Type: text/plain; charset=windows-1251
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

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:
> >=20
> > test -n "`find . -type f -newer ../src.tar.gz`" && echo hi
>=20
> 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... :)
>=20
> 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

--=20
Peter Pentchev	roam@ringlet.net    roam@sbnd.net    roam@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.

--St7VIuEGZ6dlpu13
Content-Type: text/plain; charset=windows-1251
Content-Disposition: attachment; filename="usr.bin-find-maxmatch.patch"
Content-Transfer-Encoding: quoted-printable

Index: src/usr.bin/find/extern.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 @@
=20
 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
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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;
=20
+	if (maxmatch =3D=3D 0)
+		return (0);
+
+	match =3D 0;
 	tree =3D fts_open(paths, ftsoptions, (issort ? find_compare : NULL));
 	if (tree =3D=3D 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 =3D 1;
+	}
 	return (rval);
 }
Index: src/usr.bin/find/function.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 @@
 }
=20
 /*
+ * -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 =3D nextarg(option, argvp);
+	if (dstr[0] =3D=3D '-')
+		/* all other errors handled by find_parsenum() */
+		errx(1, "%s: %s: value must be positive", option->name, dstr);
+
+	new =3D palloc(option);
+	if (option->flags & F_MAXDEPTH)
+		maxmatch =3D find_parsenum(new, option->name, dstr, NULL);
+	else
+		minmatch =3D 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 =3D=3D maxmatch)
+		exit(0);
 	return 1;
 }
=20
@@ -1238,6 +1271,9 @@
 {
 	fputs(entry->fts_path, stdout);
 	fputc('\0', stdout);
+	match++;
+	if (match =3D=3D maxmatch)
+		exit(0);
 	return 1;
 }
=20
Index: src/usr.bin/find/main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 =3D -1, maxdepth =3D -1; /* minimum and maximum depth */
+int minmatch =3D -1, maxmatch =3D -1; /* minimum and maximum number of mat=
ches */
+int match;			/* current number of matches */
 int regexp_flags =3D REG_BASIC;	/* use the "basic" regexp by default*/
=20
 static void usage(void);
Index: src/usr.bin/find/option.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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 },

--St7VIuEGZ6dlpu13--

--qtZFehHsKgwS5rPz
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (FreeBSD)

iD8DBQFA9/Mi7Ri2jRYZRVMRAmr2AJ0c6cKLKCiOxz2baDJQR2FIGZavBACgiwVM
wLAHFm1a8iuaUpmpRzdMR5E=
=cnzE
-----END PGP SIGNATURE-----

--qtZFehHsKgwS5rPz--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040716152418.GB1589>