Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

In Linux and Unix systems there are two common search commands: locate and find.

What are the pros and cons of each? When one have benefits over the other?

share|improve this question
5  
See e.g. superuser.com/questions/199472/… –  jofel Jan 3 '13 at 17:23

3 Answers 3

up vote 55 down vote accepted

locate(1) has only one big advantage over find(1): speed.

find(1), though, has many advantages over locate(1):

  • find(1) is primordial, going back to the very first version of AT&T Unix. You will even find it in cut-down embedded Linuxes via Busybox. It is all but universal.

    locate(1) is much younger and nonstandard.

    The earliest ancestor of locate(1) appeared in 1983, but it wasn't widely shipped as "locate" until 1990. BSD didn't adopt it until 1994, in 4.4BSD.

    There are three main flavors of locate(1) in the wild today. In increasing order of features, they are BSD locate, mlocate, and GNU locate. The BSDs and Mac OS X ship BSD locate. Most Linuxes ship GNU locate, but Red Hat Linuxes and Arch ship mlocate instead.

    Recent versions of GNU locate and mlocate implement all BSD locate options. mlocate implements 6 additional options not in BSD locate: -b, -e, -P, -q, --regex and -w. GNU locate implements those six plus another four: -A, -D, -E, and -p. (I'm ignoring aliases and minor differences like -? vs -h vs --help.)

    The big iron Unixes don't ship any implementation of locate. (See the man page indexes for Solaris, AIX and HP-UX.)

    Bottom line, you can't count on locate to be available on all machines, and where present, you can't count on consistent behavior between implementations.

  • find(1) has a powerful expression syntax, with many functions, Boolean operators, etc.

  • find(1) can select files by more than just name. It can select by:

    • age
    • size
    • owner
    • file type
    • timestamp
    • permissions
    • depth within the subtree...
  • When finding files by name, you can search using file globbing syntax in all versions of find(1), or in GNU or BSD versions, using regular expressions.

    Current versions of locate(1) accept glob patterns as find does, but BSD locate doesn't do regexes at all. If you're like me and have to use a variety of machine types, you find yourself preferring grep filtering to developing a dependence on -r or --regex.

    locate needs strong filtering more than find does because...

  • find(1) doesn't necessarily search the entire filesystem. You typically point it at a subdirectory, a parent containing all the files you want it to operate on. locate(1) simply spews up everything[*] it knows, leaving it to grep filtering and such to cut its eruption down to size.

  • find(1) can do things to files it finds, in addition to just finding them. The most powerful and widely supported such operator is -exec, but there are others. In recent GNU and BSD find implementations, for example, you have the -delete and -execdir operators.

  • find(1) runs in real time, so its output is always up to date.

    Because locate(1) relies on a database updated hours or days in the past, its output can be outdated. (This is the stale cache problem.) This coin has two sides:

    1. locate can name files that no longer exist.

      GNU locate and mlocate have the -e flag to make it check for file existence before printing out the name of each file it discovered in the past, but this eats away some of the locate speed advantage, and isn't available in BSD locate besides.

    2. locate will fail to name files that were created since the last database update.

    You learn to be somewhat distrustful of locate output, knowing it may be wrong.

  • find(1) never has any more privilege than the user running it.

    Because locate provides a global service to all users on a system, it wants to have its updatedb process run as root so it can see the entire filesystem. This leads to a choice of security problems:

    1. Run updatedb as root, but make its output file world-readable so locate can run without special privileges. This effectively exposes the names of all files in the system to all users. This may be enough of a security breach to cause a real problem.

      BSD locate is configured this way on Mac OS X and FreeBSD.

    2. Write the database as readable only by root, and make locate setuid root so it can read the database. This means locate effectively has to reimplement the OS's permission system so it doesn't show you files you can't normally see. It also increases the attack surface of your system, specifically risking a root escalation attack.

    3. Create a special "locate" user or group to own the database file, and mark the locate binary as setuid/setgid for that user/group so it can read the database. This doesn't prevent privilege escalation attacks by itself, but it greatly mitigates the damage one could cause.

      mlocate is configured this way on Red Hat Enterprise Linux.

      You still have a problem, though, because if you can use a debugger on locate or cause it to dump core you can get at privileged parts of the database.

    I don't see a way to create a truly "secure" locate command, short of running it separately for each user on the system, which negates much of its advantage over find(1).

Bottom line, both are very useful. locate(1) is better when you're just trying to find a particular file by name, which you know exists, but you just don't remember where it is exactly. find(1) is better when you have a focused area to examine, or when you need any of its many advantages.


[*] Obviously if you have a variant of locate(1) like slocate(1), an unprivileged user might not get literally everything out of it that it knows in its database.

share|improve this answer
10  
+1 Way better than the Super User answers –  César Jan 3 '13 at 19:11
    
Sorry, I overlooked the "slocate" paragraph. rlocate addresses the stale cache issue. You may want to mention some of the quirks of find, like find -- "$dir" not robust ($dir may be taken for a predicate), no way to test for the attributes of a symlink, race condition issues... For me find and locate address two different problems. There are many places where using find is not realistic (like directories containing millions of files). locate is an indexing system limited to file names. –  Stéphane Chazelas Jan 4 '13 at 10:26
    
First implementations of locate was roughly someting like find / -type f | gzip > locate.gz, and zgrep "$1" <locate.gz –  F. Hauri Jan 5 '13 at 14:35
    
@F.Hauri: Interesting trivia. Here's more: GNU locate is in the findutils package, and its updatedb program is implemented in terms of find(1). So in that sense, locate(1) actually requires find(1). :) –  Warren Young Jan 8 '13 at 21:45
1  
@nuttyaboutnatty: It's an ancient convention in Unix manuals, meaning manual section 1. While it is true that there is no find, locate, etc. in other sections so it doesn't have to be there to disambiguate the same name used in different sections of the manual (e.g. unlink(1) vs unlink(2)), those of us used to the convention see that as a man page reference. –  Warren Young Mar 15 '13 at 17:11

locate uses a prebuilt database, which should be regularly updated, while find iterates over a filesystem to locate files.

Thus, locate is much faster than find, but can be inaccurate if the database -can be seen as a cache- is not updated (see updatedb command).

Also, find can offer more granularity, as you can filter files by every attribute of it, while locate uses a pattern matched against file names.

share|improve this answer

find is not possible for a novice or occasional user of Unix to successfully use without careful perusal of the man page. Historically, some versions of find didn't even default the -print option, adding to the user-hostility.

locate is less flexible, but far more intuitive to use in the common case.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.