GNU find tips (again!)

I am reminded of one fact (by this post) about find that you may not be aware of (or have forgotten). The find command, by default, does not follow symbolic links: they are just another file for find to scan.

In order for a symbolic link to be recognized and used in its usual manner, the -follow option is needed.

This brings up another point about find that will clear up some confusion, even for experts. The find command mixes standard options (which change its overall behavior) with conditionals (picking and choosing files). Thus, some options can occur anywhere and change the operation of find as a whole; others are used in an implicit command line conditional. The man page calls these options “position-independent terms”.

So, even though a find option appears after the -a option (AND operator) it could actually be a true option to find, changing the command’s behavior (and thus not be relevant to the -a “option”).

The previously mentioned -follow option is a true option. However, options like -name, -a, -o, -size are all conditionals. If you keep this in mind, the occasional option in the middle of a conditional will not throw you.

The HP-UX man page for find lists the following position-independent terms:

  • -depth
  • -follow
  • -fsonly
  • -xdev

Let’s consider some more ideas on how we can use find to help us daily.

If this hasn’t been mentioned already, the -nouser and -nogroup options can be quite useful in a cron job for finding files that don’t have a proper user or group associated with them (these files are a security risk):

find / -nouser -o -nogroup -print

As we discussed earlier, using find in automated mode with an rm command is not a good idea – but at the command line, there is a replacement for -exec that will provide you with a safety net: -ok:

find . -name "f*" -ok rm -f {} \;

This command is functionally equivalent to:

find . -name "f*" | xargs rm -i

Both commands will prompt you as to whether you want to erase the file found or not.

The option -xdev is a favorite of mine: don’t follow any mount points. So if you want to search /tmp for various files but have things mounted in /tmp/mnt or other locations, this command will allow you to skip files under such mountpoints:

find /tmp -xdev -name "foo*"

This will find /tmp/foobar – but not /tmp/mnt/fooey.

An enhancement to the -exec command can improve performance – and reduce the need for xargs. Instead of terminating the command string with a semicolon (;), terminate it with a plus sign (+) right after the {} which signifies the location of the filenames in the command line:

find /tmp -name "f*" -exec ls -ld {}\+

The plus (+) is escaped, just like the semicolon would be, since the shell recognizes both characters as special characters; the backslash makes the shell treat them like any other character.

2 thoughts on “GNU find tips (again!)”

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: