October 31, 2005

CLI Magic: GNU find

Author: Joe Barr

Don't you just hate it when you can't find a file you need, but you know it's on your computer? Wouldn't you like an easy way to track down files anywhere on your computer? If so, I have good news for you, a command available to you at the friendly Linux CLI called find.

You know what they say, the CLI is such an essential part of the operating system that running an OS without one is like traveling blind. Getting to know the GNU find command can help you better understand why that is true. Climb down out of your GUI for awhile, and let's see what we can find.

The find command allows you to find a file or files by searching for them in a number of ways. Leaving aside the options for symbolic links -- we'll get to those in a minute -- the basic format for the command is as follows:


find path expression

The expression part of the command normally includes our search directives and ends with the default -- and therefore not stated -- option to print the results. Sometimes the expression is more sophisticated: it can also be used to tell find to execute specific tests, execute a command, or delete a file. We won't stray far from the default usage.

Follow this path

You don't have to specify a path where you want find to begin its search. If you do, it will begin at the point you specify and work its way down the file tree from there. If you don't, it will begin in the current directory, then work down from there.

Here's a quick example. Assuming that you have not changed directories since opening the terminal, the working directory when you run the find command will be your home directory (usually something like /home/username). Let's say that you have three sub-directories in your home directory: downloads, documents, and development. Let's also say that you are looking for a file called foobar.txt and a file called foobar.txt exists in three different places on your system: in /home/username/downloads, in /etc, and in /usr/local/share.

If we tell find to locate it without specifying the path, just giving it the file name to look for, like this:


find -name foobar.txt

then only the instance of foobar.txt in /home/username/downloads will be found.

If we broaden the search by specifying a point a little higher up the file tree, like this one:


find /usr -name foobar.txt

then the instance of foobar.txt in /usr/local/share will be found, but not the other two.

The only way to find every instance of the file is to start at the very top of the filesystem, like this:


find / -name foobar.txt

The following partial skeleton the filesystem tree may help you visualize what's happening a little more clearly.

/
	/bin
	/boot
	/dev
	/etc
	/etc/foobar.txt
	/home
	/home/username
	/home/username/downloads
	/home/username/downloads/foobar.txt
	/lib
	/mnt
	/opt
	/proc
	/root
	/sbin
	/srv
	/sys
	/usr
	/usr/local
	/usr/local/share
	/usr/local/share/foobar.txt
	/var

In the first case, the starting point was /home/username, so the three sub-directories beneath and within that point were searched, finding one instance of the file.

In the second case, when /usr was given as the starting point, the instance living in /usr/share/local was found.

In the final case, which started at the very top of the file tree, all instances were found.

This may be a good time to mention that find results are limited by your permissions to read files and directories. For a system-wide search, you'll get best results by running as root.

By the way, it's not necessary to provide the complete file name. You can use the first few characters of the name if you like. Find will list all the instances of files that match whatever portion of a name you enter.

Search this way

In the examples above, we used the -name option to specify the file name to search for, but that's just the tip of the iceberg of its search capabilities. Find can search by name, timestamp, type of file, and much more. Wondering what happened to all your MP3 files? Here's one way to find out:


find / -iname '*.MP3'

Notice the use of -iname instead of simply -name in the example above: that makes the search case-insensitive. Also note the single-quote marks around the name itself, required by the use of the * metacharacter in the name.

If you're forgetful like me, you may sometimes need help finding a file you created or modified just an hour ago because you can't remember its name. You can still use find to locate it. Instead of using find with the -name option, use find -amin -60 to see a list of all files accessed within the past 60 minutes. Note the minus sign before the 60 in that example. In this context, it means less than. If you leave it off, you will only see files accessed exactly 60 minutes ago, or if you use a plus sign instead of the minus, files accessed more than 60 minutes ago.

Symbolic links

Now about those symbolic link options we bypassed at the very start. Let's take a look at them now. The find command has only three of them: -H, -L, and -P. You may or may not know that symbolic links are a special case. Their sole function is to point the way to a real file that they have been created to represent, but they have their own properties which may be completely different than those of the real file. That's important to our discussion of find because those properties are often reported by find as the result of its search of the filesystem. Note that these options were implemented in the 4.2.14 release of the GNU findutils, so older versions of GNU find will not support the symbolic link options.

The default is -P, and it means never follow symbolic links. That means that unless you tell find otherwise, any properties find reports about a symbolic link belong to the symbolic link itself, not the file it links to.

Conversely, if you specify -L on the command line, you are telling find to follow the link to the file pointed to and use its properties instead.

And finally, if you specify the -H option, then if a file name given in the command line itself is a symbolic link, it is to be followed, but only the file name given in the command itself. All other symbolic links uncovered by the search are not followed.

As usual, we are just making an introduction here. There are many other useful ways to search with find. The -perm option selects files by their permissions; the -size option by file size; and the -type option by file type, including named pipes and sockets. You can also search by file owner or group, and the list goes on.

For those of us just getting started with the find command, the default works just fine. As always, turn to the man pages for additional info. As an intermediate step, you might consider using find --help before wading through the find man page, which is fairly lengthy. Note that I've covered the GNU find command here -- other versions of find have slightly different syntax.

That's it for this week, except for one question. When I first started running Linux, one of the most popular security tips making the rounds was a quick and easy way to check to see what programs on your system were SUID. Anybody remember what that was? Be the first to provide the answer in a comment and win a free, one-year subscription to the man pages.

Category:

  • Linux
Click Here!