Subject: multi find with different file outputs
To: None <tech-userlevel@netbsd.org>
From: Jeremy C. Reed <reed@reedmedia.net>
List: tech-userlevel
Date: 09/24/2005 23:15:39
I'd like to patch up find(1) to add option to have it output to different
file outputs.
I have a patch for my idea #3 below.
Please share your comments (and examples) of how you would do this for the
user interface.
Three different ideas below:
1)
find --output 1 /etc -perm -0002 \; --output my.files / -user ${USER}
Man page description under options (not primaries):
-O _file_
--output _file_
Write to this output file. The following options and expressions
up to the semicolon (or end of command arguments) will be used for
this output. If _file_ is numeric, then write to the file descriptor
instead. This option can be used so one find process can do
multiple tasks. If no -O option is used, then it writes to default
standard output.
2) Or maybe I should only allow the [file ...] to be set one time, so then
a example could be like:
find / -O 3 -perm -0002 \; -user nobody > list.of.nobody.owned.files \
3>world.writable.files
If using -exec maybe two semicolons would be needed for example:
find / -name "lyx.core" -exec rm "{}" \; \; -O my.files -user $USER
To do one find over / and remove all lyx.core files and save to a file
called my.files all files owned by me.
I'll also have to think about -prune and -maxdepth, -mindepth related
behaviour. Because just because one output doesn't descent into a
directory, another output may need to.
3) Another idea could be:
find / \( -name "*.core" -output 5 \) -o \( -user joe -output 6 \) \
5>core.dumps 6>joes.files
or
find / \( -name "*.core" -output core.dumps \) \
-also \( -user joe -output joes.files \)
I use -also because -o means it would skip next if first was successful
and -and means that both need to be successful. I am not sure yet.
And this could be similar to -print and could also have a -output0 to
separate with null characters and also outputx.
I have coded up a test:
Index: extern.h
===================================================================
RCS file: /cvsroot/src/usr.bin/find/extern.h,v
retrieving revision 1.20
diff -b -u -r1.20 extern.h
--- extern.h 7 Aug 2003 11:13:40 -0000 1.20
+++ extern.h 25 Sep 2005 06:13:34 -0000
@@ -73,6 +73,7 @@
PLAN *c_newer __P((char ***, int));
PLAN *c_nogroup __P((char ***, int));
PLAN *c_nouser __P((char ***, int));
+PLAN *c_output __P((char ***, int));
PLAN *c_path __P((char ***, int));
PLAN *c_perm __P((char ***, int));
PLAN *c_print __P((char ***, int));
Index: find.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/find.c,v
retrieving revision 1.18.2.1
diff -b -u -r1.18.2.1 find.c
--- find.c 31 Mar 2004 18:07:46 -0000 1.18.2.1
+++ find.c 25 Sep 2005 06:13:34 -0000
@@ -102,7 +102,7 @@
* is assumed so we bracket the current expression with parens, if
* necessary, and add a -print node on the end.
*/
- if (!isoutput) {
+ if (0 == isoutput) {
if (plan == NULL) {
new = c_print(NULL, 0);
tail = plan = new;
Index: find.h
===================================================================
RCS file: /cvsroot/src/usr.bin/find/find.h,v
retrieving revision 1.18
diff -b -u -r1.18 find.h
--- find.h 7 Aug 2003 11:13:41 -0000 1.18
+++ find.h 25 Sep 2005 06:13:34 -0000
@@ -44,7 +44,7 @@
N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS, N_FOLLOW, N_FSTYPE, N_GROUP,
N_INAME, N_INUM, N_IREGEX, N_LINKS, N_LS, N_MINDEPTH, N_MAXDEPTH,
N_MMIN, N_MTIME, N_NAME, N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK,
- N_OPENPAREN, N_OR, N_PATH, N_PERM, N_PRINT, N_PRINT0, N_PRINTX,
+ N_OPENPAREN, N_OR, N_OUTPUT, N_PATH, N_PERM, N_PRINT, N_PRINT0, N_PRINTX,
N_PRUNE, N_REGEX, N_SIZE, N_TYPE, N_USER, N_XDEV
};
Index: function.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/function.c,v
retrieving revision 1.46
diff -b -u -r1.46 function.c
--- function.c 7 Aug 2003 11:13:41 -0000 1.46
+++ function.c 25 Sep 2005 06:13:37 -0000
@@ -61,7 +61,7 @@
#include <unistd.h>
#include "find.h"
-#include "stat_flags.h"
+#include "../../bin/ls/stat_flags.h"
#define COMPARE(a, b) { \
switch (plan->flags) { \
@@ -102,6 +102,7 @@
int f_newer __P((PLAN *, FTSENT *));
int f_nogroup __P((PLAN *, FTSENT *));
int f_nouser __P((PLAN *, FTSENT *));
+ int f_output __P((PLAN *, FTSENT *));
int f_path __P((PLAN *, FTSENT *));
int f_perm __P((PLAN *, FTSENT *));
int f_print __P((PLAN *, FTSENT *));
@@ -1202,6 +1203,40 @@
return (palloc(N_NOUSER, f_nouser));
}
+/* -output functions --
+ *
+ * Causes the current pathame to be written to
+ * the defined output file or file handle.
+ */
+int
+f_output(plan, entry)
+ PLAN *plan;
+ FTSENT *entry;
+{
+/* testing with file handle 2 for now */
+ (void)fprintf(&__sF[2], "%s\n", entry->fts_path);
+ return(0); /* return false so it will continue */
+}
+
+PLAN *
+c_output(argvp, isok)
+ char ***argvp;
+ int isok;
+{
+/* need to do */
+ char *filename = **argvp;
+ PLAN *new;
+
+ isoutput = 2; /* do not default to -print */
+
+ (*argvp)++;
+ new = palloc(N_OUTPUT, f_output);
+ new->c_data = filename;
+ return (new);
+/* todo: need to use this */
+}
+
+
/*
* -path functions --
*
Index: option.c
===================================================================
RCS file: /cvsroot/src/usr.bin/find/option.c,v
retrieving revision 1.20
diff -b -u -r1.20 option.c
--- option.c 7 Aug 2003 11:13:43 -0000 1.20
+++ option.c 25 Sep 2005 06:13:37 -0000
@@ -92,6 +92,7 @@
{ "-o", N_OR, c_or, 0 },
{ "-ok", N_OK, c_exec, 1 },
{ "-or", N_OR, c_or, 0 },
+ { "-output", N_OUTPUT, c_output, 1 },
{ "-path", N_PATH, c_path, 1 },
{ "-perm", N_PERM, c_perm, 1 },
{ "-print", N_PRINT, c_print, 0 },
(Ignore the patch for including stat_flags.h above.)
To use above patch's idea, you must use -print for other expressions. For
example:
rainier:/usr/src/src/usr.bin/find$ ./find /etc \( -group operator -output
5 \) -o \( -name "*pass*" -print \) 2>J
/etc/rc.d/yppasswdd
/etc/passwd.conf
/etc/master.passwd
/etc/passwd
rainier:/usr/src/src/usr.bin/find$ cat J
/etc/dumpdates
/etc/skeykeys
find: /etc/cgd: Permission denied
I am only using stderr for testing now. But that works great.
Any thoughts on this?
Jeremy C. Reed
technical support & remote administration
http://www.pugetsoundtechnology.com/