martin@mwtech.UUCP (Martin Weitzel) (03/22/90)
In article <22817@adm.BRL.MIL> konczal@mail-gw.ncsl.nist.gov (Joseph C. Konczal) writes: >| echo "" >| echo "* Directories that can be written to by everyone:" >| ls -lR / | awk '/^d[rwx]......w[x-]/ { print }' >| echo "" >| echo "* Directories with search permissions for everyone:" >| ls -lR / | awk '/^d[rwx]......w[x-]/ { print }' > >Replace the ls ... lines with: > >find / -type d -perm -0002 -print > >find / -type d -perm -0001 -print Or replace the two 'find's by only one: find / \( -type d -perm -0002 -o -type d -perm -0001 \) -print Now 'find' has only to make one scan thrue the entire hierachy of directories (which is a time consuming part of its work). Most people who have a little experience with find know the above, but often they seem not to know that 'find' can also do *different* things during *one* single scan thrue the directories. (In fact, this feature is not so obvious from RTFMing.) Basically, a '-print', '-exec' or '-ok' is just like a condition that can be *AND*-ed with other conditions. Evaluation of AND-ed conditions is terminated as soon as the result turns out to be FALSE (much like with && in C) so a '-print' is not evaluated, if the condition(s) to the left evaluate to FALSE. You also can do OR-ing several AND-ed conditions, which will make more complex 'find' commands look as follows: find path \ list-of-tests print-or-exec-something \ -o list-of-tests print-or-exec-something \ -o list-of-tests print-or-exec-something \ -o list-of-tests print-or-exec-something \ -o list-of-tests print-or-exec-something \ -o print-or-exec-soemthing-for-the-default-case These examples work, because OR-ed conditions *are* evaluated even if the result allready turns out to be TRUE (*NOT* like with || in C!) Normally you are only interested in the "side effects" of a '-print' (printing the file name), but the utility of '-exec' extends beyond its side effects: In contrary to '-print', which allways evaluates to TRUE, '-exec' evaluates to the return status of the executed command. So it is easy to test for conditions which are not among the "builtin" tests of 'find'. You simply write a command (or shell procedure) which tests for the special condition and let it return a TRUE (zero) or FALSE (non-zero) exit status. Such a call to 'find' may then look as follows: find path builtin-test -exec spc-test {} \; -print It is recommendable to place such a special test *after* the builtins (though it would also work swapped), because it forks and execs a new process which could be avoided if the builtin test evaluates to FALSE. Finally note that '-ok' is a little exceptional as it evaluates to FALSE not only if the executed command returns a non-zero exit status, but also if you don't respond "y" to its prompt. Look at the following example: find path \ first-builtin-test -ok command {} \; \ second-builtin-test -exec other-command {} \; \ -print Try to figure out what it does, before you continue reading ... Answer: If first-builtin-test evaluates to TRUE 'find' prompts you with command and *if* you answer 'y' AND the commands exit status is zero AND the second-builtin-test is TRUE, then other-command is executed. Finally, if other-command too exits with status zero the name of the file is printed. If you would not have answered 'y' then neither the second-builtin-test would have been evaluated, nor other-command would have a chance to execute. Easy, not so? :-) I cross-post this to c.u.q and redirected followups there, but I leave this article in c.u.w, because it is a followup to an article of this group. I apologize if my tutorial about the advanced usage of 'find' is vital knowledge among the readers of this group. P.S.: The BUGS section of the 'find' command in the early UPM contained the remark: "The syntax is painfull". IMHO, the author could well have appended "but well thought". -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83