find: Adding Tests

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