Linux.com

Feature: Linux

CLI Magic: GNU find

By Joe Barr on October 31, 2005 (8:00:00 AM)

Share    Print    Comments   

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.

Share    Print    Comments   

Comments

on CLI Magic: GNU find

Note: Comments are owned by the poster. We are not responsible for their content.

What's all this n00bage

Posted by: Anonymous Coward on October 31, 2005 08:15 PM
how about a link to man or something aswell as such a short story. Not much of a time related story: find has been out for ages.

usage:

cd /

find -name name

#

find suids

Posted by: Anonymous Coward on October 31, 2005 06:49 PM
find / -perm -4000

man find<nobr> <wbr></nobr>;)

#

Finding suid files

Posted by: Anonymous Coward on October 31, 2005 07:02 PM
<tt>find / -type f -perm +4000 -uid 0 -ls</tt>
lists suid 0 files on your system. You can also use +2000 to find sgid or +6000 to find suid OR sgid stuff.

#

How to things from the search path

Posted by: Anonymous Coward on October 31, 2005 08:00 PM
Sometimes you may want to exclude parts of the directory tree. It took me a while to figure out how to do this because it isn't very intuitive.
If you wanted to search for foo.txt but don't want to descend into<nobr> <wbr></nobr>/proc or<nobr> <wbr></nobr>/dev you can do this
find / -path '/proc' -prune -o -path '/dev' -prune -o -name foo.txt

The '-o' means 'or', so there in this case there are three conditions, separated by 'or', which will cause find to take action. The first two is when the path is '/proc' or '/dev' the action find will take is to prune them from the search path. The third condition is when the name is foo.txt. In this case find will print, since no other action is specified.

See man find for more info.

#

Back Pain relief

Posted by: Anonymous Coward on May 28, 2006 01:57 PM
[URL=http://painrelief.fanspace.com/index.htm] Pain relief [/URL]
[URL=http://lowerbackpain.0pi.com/backpain.htm] Back Pain [/URL]
[URL=http://painreliefproduct.guildspace.com] Pain relief [/URL]
[URL=http://painreliefmedic.friendpages.com] Pain relief [/URL]
[URL=http://nervepainrelief.jeeran.com/painrelief<nobr>.<wbr></nobr> htm] Nerve pain relief [/URL]

#

Don't forget locate

Posted by: Anonymous Coward on October 31, 2005 08:22 PM
find is very good I admit but for a quick file search on your system.... use locate . locate is in the slocate package available on most linux distros and there are even packages for other platforms.

#

Re:Don't forget locate

Posted by: Anonymous Coward on October 31, 2005 08:33 PM
Locate just uses find, and isn't as controllable.

In addition, linux.com had an article about locate a ways back anyways.

#

Re:Don't forget locate

Posted by: Anonymous Coward on October 31, 2005 08:40 PM
er em, locate does not use find, it uses the database built by updatedb, that why its a bazillion times faster than find; if somewhat out of date.

Locate also supports regular experssions.

#

Re:Don't forget locate

Posted by: Anonymous Coward on November 01, 2005 02:53 AM
updatedb is a shell script that uses the find command.

#

Re:Don't forget locate

Posted by: Anonymous Coward on November 01, 2005 01:16 PM
don't forget about rlocate which updates a db in real time<nobr> <wbr></nobr>...

"rlocate provides a secure way to index and quickly search for files on your system. This locate is always up-to-date with the help of rlocate kernel module. It uses incremental encoding just like GNU locate to compress its database to make searching faster, but it will also ensure that users will not see files they do not have access to."

#

Re:Don't forget locate

Posted by: Anonymous Coward on November 01, 2005 04:45 PM
It doesn't use it everytime you search though, which is what the OP was getting at.

#

GNU/find for dummies, part 1

Posted by: Anonymous Coward on October 31, 2005 08:41 PM
<a href="http://slackworld.berlios.de/02/classes.html" title="berlios.de">http://slackworld.berlios.de/02/classes.html</a berlios.de>

A _much_ more comprehensive doc.<nobr> <wbr></nobr>;-)

#

Re:GNU/find for dummies, part 1

Posted by: Joe Barr on November 01, 2005 12:13 AM
That is a fine piece. Thanks for the link.


Joe Barr

#

use with grep

Posted by: Anonymous Coward on October 31, 2005 11:50 PM
If I dont remember wrong, I used to use the 'find' command together with 'grep', maybe I didnt know how to use the find command, but piping it to grep helped me.

'locate' is also a useful command.<nobr> <wbr></nobr>:)

#

...misses the point a little..

Posted by: Anonymous Coward on November 01, 2005 12:25 AM
I've probably done the same thing, but it sort of defeats the purpose of using 'find' in the first place. If you're going to do your pattern matching with grep, you're probably just as well off using "ls -aR |grep (whatever)".. it's somewhat faster.

On the other hand, find (once you learn its capabilities) has alot more to offer. Even the basic '-iname *.mp3' is handy; you can combine boolean comparisons together in a single command-line (think -iname *.mp3 -or -iname *.ogg). find can also perform actions on its results rather than just listing them (think 'find -iname *.swp -or -iname *~ -delete', for example), which really helps for scriptability. (Check out the man page to really get a feel for the capabilities; if you're looking for a single command to delete all files under a directory matching a regex and older than a certain age.. find is absolutely for you.

#

Don't forget -exec!

Posted by: Anonymous Coward on November 01, 2005 10:51 PM
Don't forget about -exec, one very handy part of find. Very useful when there are too many files in a directory for example.

find / -name '*.jpg' -exec mv {} {}.old \;

The above would search recursively through and rename all<nobr> <wbr></nobr>.jpg files to<nobr> <wbr></nobr>.jpg.old. Probably not the best example, but extreemly useful.

#

be sure to check out -exec option

Posted by: Anonymous Coward on November 02, 2005 12:41 AM
If you want to run a particular command on each file found, specify the command with -exec and find will spawn the command processes for you, substituting each specific file in the -exec command string. Especially useful if you are unwilling to put in the effort to learn actual shell scripting (it's not that bad, really, just watch out for quoting gotchas!).

#

sorry for the duplicate post about -exec

Posted by: Anonymous Coward on November 02, 2005 12:45 AM
...but I swear comment #86040 wasn't there when I submitted mine...

#

Back Pain relief

Posted by: Anonymous Coward on May 30, 2006 01:22 AM
[URL=http://nervepainrelief.jeeran.com/painrelief<nobr>.<wbr></nobr> htm] Nerve pain relief [/URL]

  [URL=http://www.back.painreliefnetwork.net/lowbac<nobr>k<wbr></nobr> pain.htm] Low back pain [/URL]

  [URL=http://blog.gala.net/uploads/painreliefback/<nobr>b<wbr></nobr> ackpainrelief.htm] Back pain relief [/URL]

  [URL=http://www.weblog.ro/usercontent/13155/profi<nobr>l<wbr></nobr> es/kneepainrelief.htm] Knee pain relief [/URL]

  [URL=http://www.info.painreliefnetwork.net/Pain-R<nobr>e<wbr></nobr> lief.html] Pain relief [/URL]

  [URL=http://www.sitefights.com/community/scifi/pa<nobr>i<wbr></nobr> nrelief/painreliefpreved.htm] Pain relief [/URL]

  [URL=http://www.info.painreliefnetwork.net/Medica<nobr>t<wbr></nobr> ion-Pain-Relief.html] Medication pain relief [/URL]

  [URL=http://www.info.painreliefnetwork.net/Natura<nobr>l<wbr></nobr> -Pain-Relief.html] Natural pain relief [/URL]


  [URL=http://painrelief.fanspace.com/index.htm] Pain relief [/URL]

  [URL=http://lowerbackpain.0pi.com/backpain.htm] Back Pain [/URL]

  [URL=http://painreliefproduct.guildspace.com] Pain relief [/URL]
[URL=http://painreliefmedic.friendpages.com] Pain relief [/URL]

#

Use with xargs!

Posted by: Anonymous Coward on November 02, 2005 04:29 PM
This is common for me:


    find . -name '*.java' | xargs grep MyHiddenClass

This will list out all occurences in the files where MyHiddenClass are used in my project. (Aka CLI oriented IDE.<nobr> <wbr></nobr>:-))


    -Jon

#

Re:GNU/find for dummies, part 1

Posted by: Anonymous Coward on November 02, 2005 09:20 PM
My pleasure. I'm glad you liked it.<nobr> <wbr></nobr>:-)

Mikhail Zotov

#

find and grep working together

Posted by: Administrator on November 01, 2005 08:10 AM
I wrote this up a while back which describes
techniques for using find and grep for recursive
searches.

<a href="http://www.insanum.com/unix/cli-fun-recursive-search/" title="insanum.com">http://www.insanum.com/unix/cli-fun-recursive-sea<nobr>r<wbr></nobr> ch/</a insanum.com>

#

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya