find: Adding Tests

1 
1 3.5 Adding Tests
1 ================
1 
1 You can test for file attributes that none of the 'find' builtin tests
1 check.  To do this, use 'xargs' to run a program that filters a list of
1 files printed by 'find'.  If possible, use 'find' builtin tests to pare
1 down the list, so the program run by 'xargs' has less work to do.  The
1 tests builtin to 'find' will likely run faster than tests that other
1 programs perform.
1 
1    For reasons of efficiency it is often useful to limit the number of
1 times an external program has to be run.  For this reason, it is often a
1 good idea to implement "extended" tests by using 'xargs'.
1 
1    For example, here is a way to print the names of all of the
1 unstripped binaries in the '/usr/local' directory tree.  Builtin tests
1 avoid running 'file' on files that are not regular files or are not
1 executable.
1 
1      find /usr/local -type f -perm /a=x | xargs file |
1        grep 'not stripped' | cut -d: -f1
1 
1 The 'cut' program removes everything after the file name from the output
1 of 'file'.
1 
11    However, using 'xargs' can present important security problems (⇒
 Security Considerations).  These can be avoided by using '-execdir'.
1 The '-execdir' action is also a useful way of putting your own test in
1 the middle of a set of other tests or actions for 'find' (for example,
1 you might want to use '-prune').
1 
1    To place a special test somewhere in the middle of a 'find'
1 expression, you can use '-execdir' (or, less securely, '-exec') to run a
1 program that performs the test.  Because '-execdir' evaluates to the
1 exit status of the executed program, you can use a program (which can be
1 a shell script) that tests for a special attribute and make it exit with
1 a true (zero) or false (non-zero) status.  It is a good idea to place
1 such a special test _after_ the builtin tests, because it starts a new
1 process which could be avoided if a builtin test evaluates to false.
1 
1    Here is a shell script called 'unstripped' that checks whether its
1 argument is an unstripped binary file:
1 
1      #! /bin/sh
1      file "$1" | grep -q "not stripped"
1 
1    This script relies on the shell exiting with the status of the last
1 command in the pipeline, in this case 'grep'.  The 'grep' command exits
1 with a true status if it found any matches, false if not.  Here is an
1 example of using the script (assuming it is in your search path).  It
1 lists the stripped executables (and shell scripts) in the file 'sbins'
1 and the unstripped ones in 'ubins'.
1 
1      find /usr/local -type f -perm /a=x \
1        \( -execdir unstripped '{}' \; -fprint ubins -o -fprint sbins \)
1